基于TimeLine模型的消息同步機(jī)制-創(chuàng)新互聯(lián)

我們當(dāng)前的IM雖然進(jìn)行了微服務(wù)化,但是核心的消息投遞模式仍然采用下圖描繪的方式,參看《一個(gè)海量在線用戶即時(shí)通訊系統(tǒng)(IM)的完整設(shè)計(jì)》。

創(chuàng)新互聯(lián)公司主要從事網(wǎng)頁(yè)設(shè)計(jì)、PC網(wǎng)站建設(shè)(電腦版網(wǎng)站建設(shè))、wap網(wǎng)站建設(shè)(手機(jī)版網(wǎng)站建設(shè))、響應(yīng)式網(wǎng)站開發(fā)、程序開發(fā)、網(wǎng)站優(yōu)化、微網(wǎng)站、重慶小程序開發(fā)等,憑借多年來在互聯(lián)網(wǎng)的打拼,我們?cè)诨ヂ?lián)網(wǎng)網(wǎng)站建設(shè)行業(yè)積累了豐富的成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、網(wǎng)站設(shè)計(jì)、網(wǎng)絡(luò)營(yíng)銷經(jīng)驗(yàn),集策劃、開發(fā)、設(shè)計(jì)、營(yíng)銷、管理等多方位專業(yè)化運(yùn)作于一體。

基于TimeLine模型的消息同步機(jī)制

在這個(gè)方式下,消息同步的基本思路和步驟如下(序號(hào)不對(duì)應(yīng)圖中序號(hào))

1、把消息存儲(chǔ)到離線收件箱

2、向在線用戶推送消息

3、在線用戶返回收到消息的ack信息

4、服務(wù)端清除用戶此條離線消息

對(duì)于離線用戶,登錄后直接拉取離線消息即可

這個(gè)消息同步方式有它合理的地方

1、流程比較直觀

2、網(wǎng)絡(luò)交互量較少(相對(duì)于后邊的TimeLine模型而言)

但是這個(gè)方案存在更多不足的地方

1、我們有App和Web兩個(gè)端,需要為每個(gè)端都寫一份離線消息。由于離線消息是擴(kuò)散寫的,多寫一份,服務(wù)端就多一份壓力

2、消息ack回來之后,服務(wù)端需要把對(duì)應(yīng)的消息從存儲(chǔ)中刪除,這個(gè)過程性能也是一個(gè)問題

這個(gè)消息模式在比較單一的IM應(yīng)用場(chǎng)景下還是能夠勝任的。但是隨著消息場(chǎng)景越來越復(fù)雜,尤其是SDK推出以后,這個(gè)模式就存在很多弊端。SDK的應(yīng)用可能存在很多個(gè)端,服務(wù)端不可能為每個(gè)端都寫離線消息!

對(duì)于SDK,我們采用TimeLine模型來實(shí)現(xiàn)客戶端和服務(wù)端的消息同步。

以下內(nèi)容是釘釘?shù)淖龇?/strong>,比較了傳統(tǒng)架構(gòu)和現(xiàn)代架構(gòu)。而我們現(xiàn)在的IM消息同步這塊介于兩者之間。 

基于TimeLine模型的消息同步機(jī)制

傳統(tǒng)架構(gòu)下,消息是先同步后存儲(chǔ)。對(duì)于在線的用戶,消息會(huì)直接實(shí)時(shí)同步到在線的接收方,消息同步成功后,并不會(huì)進(jìn)行持久化。而對(duì)于離線的用戶或者消息無法實(shí)時(shí)同步成功時(shí),消息會(huì)持久化到離線庫(kù),當(dāng)接收方重新連接后,會(huì)從離線庫(kù)拉取所有未讀消息。當(dāng)離線庫(kù)中的消息成功同步到接收方后,消息會(huì)從離線庫(kù)中刪除。傳統(tǒng)的消息系統(tǒng),服務(wù)端的主要工作是維護(hù)發(fā)送方和接收方的連接狀態(tài),并提供在線消息同步和離線消息緩存的能力,保證消息一定能夠從發(fā)送方傳遞到接收方。服務(wù)端不會(huì)對(duì)消息進(jìn)行持久化,所以也無法支持消息漫游。

基于TimeLine模型的消息同步機(jī)制

現(xiàn)代架構(gòu)下,消息是先存儲(chǔ)后同步。先存儲(chǔ)后同步的好處是,如果接收方確認(rèn)接收到了消息,那這條消息一定是已經(jīng)在云端保存了。并且消息會(huì)有兩個(gè)庫(kù)來保存,一個(gè)是消息存儲(chǔ)庫(kù),用于全量保存所有會(huì)話的消息,主要用于支持消息漫游。另一個(gè)是消息同步庫(kù),主要用于接收方的多端同步。消息從發(fā)送方發(fā)出后,經(jīng)過服務(wù)端轉(zhuǎn)發(fā),服務(wù)端會(huì)先將消息保存到消息存儲(chǔ)庫(kù),后保存到消息同步庫(kù)。完成消息的持久化保存后,對(duì)于在線的接收方,會(huì)直接選擇在線推送。但在線推送并不是一個(gè)必須路徑,只是一個(gè)更優(yōu)的消息傳遞路徑。對(duì)于在線推送失敗或者離線的接收方,會(huì)有另外一個(gè)統(tǒng)一的消息同步方式。接收方會(huì)主動(dòng)的向服務(wù)端拉取所有未同步消息,但接收方何時(shí)來同步以及會(huì)在哪些端來同步消息對(duì)服務(wù)端來說是未知的,所以要求服務(wù)端必須保存所有需要同步到接收方的消息,這是消息同步庫(kù)的主要作用。對(duì)于新的同步設(shè)備,會(huì)有消息漫游的需求,這是消息存儲(chǔ)庫(kù)的主要作用,在消息存儲(chǔ)庫(kù)中,可以拉取任意會(huì)話的全量歷史消息。

以上是傳統(tǒng)架構(gòu)和現(xiàn)代架構(gòu)的一個(gè)簡(jiǎn)單的對(duì)比,現(xiàn)代架構(gòu)上整個(gè)消息的同步和存儲(chǔ)流程,并沒有變復(fù)雜太多,但是其能實(shí)現(xiàn)多端同步以及消息漫游?,F(xiàn)代架構(gòu)中最核心的就是兩個(gè)消息庫(kù)『消息同步庫(kù)』和『消息存儲(chǔ)庫(kù)』,是消息同步和存儲(chǔ)最核心的基礎(chǔ)。

我們看看Timeline模型是怎么樣的?

基于TimeLine模型的消息同步機(jī)制

如圖是Timeline模型的一個(gè)抽象表述,Timeline可以簡(jiǎn)單理解為是一個(gè)消息隊(duì)列,但這個(gè)消息隊(duì)列有如下特性:

  • 每個(gè)消息擁有一個(gè)順序ID(SeqId),在隊(duì)列后面的消息的SeqId一定比前面的消息的SeqId大,也就是保證SeqId一定是增長(zhǎng)的,但是不要求嚴(yán)格遞增。

  • 新的消息永遠(yuǎn)在尾部添加,保證新的消息的SeqId永遠(yuǎn)比已經(jīng)存在隊(duì)列中的消息都大。

  • 可根據(jù)SeqId隨機(jī)定位到具體的某條消息進(jìn)行讀取,也可以任意讀取某個(gè)給定范圍內(nèi)的所有消息。

有了這些特性后,消息的同步可以拿Timeline來很簡(jiǎn)單的實(shí)現(xiàn)。圖中的例子中,消息發(fā)送方是A,消息接收方是B,同時(shí)B存在多個(gè)接收端,分別是B1、B2和B3。A向B發(fā)送消息,消息需要同步到B的多個(gè)端,待同步的消息通過一個(gè)Timeline來進(jìn)行交換。A向B發(fā)送的所有消息,都會(huì)保存在這個(gè)Timeline中,B的每個(gè)接收端都是獨(dú)立的從這個(gè)Timeline中拉取消息。每個(gè)接收端同步完畢后,都會(huì)在本地記錄下最新同步到的消息的SeqId,即最新的一個(gè)位點(diǎn),作為下次消息同步的起始位點(diǎn)。服務(wù)端不會(huì)保存各個(gè)端的同步狀態(tài)(我認(rèn)為服務(wù)端也可以記錄各端的同步點(diǎn)位),各個(gè)端均可以在任意時(shí)間從任意點(diǎn)開始拉取消息。

看完TimeLine模型,我存在過困擾。既有推送又有拉取,客戶端怎么確定同步點(diǎn)位究竟在哪里呢?尤其是用戶打開軟件,拉取同步過程中有新消息到了怎么辦?

這里要感謝彬哥(LinkedIn的大牛)提示,他說他們的消息都是拉取的。既然消息是拉取的,那推送的又是什么呢?

仔細(xì)看現(xiàn)代架構(gòu)的圖,第3步寫的是“推送通知”。推送的是有新消息的提示信息,客戶端收到這個(gè)通知就拉取同步消息,客戶端和服務(wù)端各自維護(hù)這個(gè)端的同步點(diǎn)位(為了節(jié)省網(wǎng)絡(luò)交互,客戶端拉取同步消息后,不需要向服務(wù)端確認(rèn),因此客戶端和服務(wù)端維護(hù)的同步點(diǎn)位不完全一致,但是不影響業(yè)務(wù)邏輯,這個(gè)細(xì)節(jié)后續(xù)單獨(dú)寫文章介紹)。由于只存在拉取消息,同步點(diǎn)位的維護(hù)就變得很簡(jiǎn)單了,客戶端保存拉取到的最新消息的ID(SeqId)即可。

至此,支持多端的消息同步模型已經(jīng)成型。

那么這個(gè)方案還有沒有優(yōu)化空間呢?

這個(gè)方式跟我們現(xiàn)在的方式相比增加了網(wǎng)絡(luò)交互次數(shù),有沒有辦法能夠節(jié)省網(wǎng)絡(luò)開銷,有享受TimeLine模型對(duì)多端友好的支持呢?

看過一篇文章介紹微信為每個(gè)用戶的消息ID進(jìn)行了嚴(yán)格遞增編號(hào),也就是為每個(gè)用戶的TimeLine模型的消息進(jìn)行了嚴(yán)格遞增的編號(hào)。既該用戶第一條消息序號(hào)為1,第二條為2以此類推。

這樣一個(gè)編號(hào)服務(wù),開發(fā)成本還是比較高的,那微信為什么要做呢?我現(xiàn)在認(rèn)為其中一個(gè)原因是為了減少網(wǎng)絡(luò)交互。采用推通知,再拉取同步消息的方式,畢竟要多一次網(wǎng)絡(luò)交互。如果消息嚴(yán)格編號(hào),可以將傳統(tǒng)的推消息和新的推通知的方式結(jié)合起來。推往客戶端的消息帶有嚴(yán)格遞增的消息ID,客戶端可以根據(jù)消息ID計(jì)算出是否需要拉取同步消息(如果推過來的消息ID只比客戶端大的消息ID大1,則沒有必要拉取同步消息)。 

實(shí)施層面同樣存在不少挑戰(zhàn),難點(diǎn)是如何將邏輯模型映射到物理模型或具體中間件,細(xì)節(jié)后續(xù)再介紹。

名稱欄目:基于TimeLine模型的消息同步機(jī)制-創(chuàng)新互聯(lián)
文章網(wǎng)址:http://www.muchs.cn/article18/ipgdp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航、網(wǎng)站收錄App開發(fā)、響應(yīng)式網(wǎng)站域名注冊(cè)、外貿(mào)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)