Jack Jiang

          我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
          posts - 499, comments - 13, trackbacks - 0, articles - 1

          本文內(nèi)容和編寫(xiě)思路是基于鄧昀澤的“大規(guī)模并發(fā)IM服務(wù)架構(gòu)設(shè)計(jì)”、“IM的弱網(wǎng)場(chǎng)景優(yōu)化”兩文的提綱進(jìn)行的,感謝鄧昀澤的無(wú)私分享。

          1、引言

          接上篇《一套億級(jí)用戶(hù)的IM架構(gòu)技術(shù)干貨(上篇):整體架構(gòu)、服務(wù)拆分等》,本文主要聚焦這套億級(jí)用戶(hù)的IM架構(gòu)的一些比較細(xì)節(jié)但很重要的熱門(mén)問(wèn)題上,比如:消息可靠性、消息有序性、數(shù)據(jù)安全性、移動(dòng)端弱網(wǎng)問(wèn)題等。

          以上這些熱門(mén)IM問(wèn)題每個(gè)話題其實(shí)都可以單獨(dú)成文,但限于文章篇幅,本文不會(huì)逐個(gè)問(wèn)題詳細(xì)深入地探討,主要以拋磚引玉的方式引導(dǎo)閱讀者理解問(wèn)題的關(guān)鍵,并針對(duì)問(wèn)題提供專(zhuān)項(xiàng)研究文章鏈接,方便有選擇性的深入學(xué)習(xí)。希望本文能給你的IM開(kāi)發(fā)帶來(lái)一些益處。

          本文已同步發(fā)布于“即時(shí)通訊技術(shù)圈”公眾號(hào),歡迎關(guān)注。公眾號(hào)上的鏈接是:點(diǎn)此進(jìn)入

          2、系列文章

          為了更好以進(jìn)行內(nèi)容呈現(xiàn),本文拆分兩了上下兩篇。

          本文是2篇文章中的第2篇:

          一套億級(jí)用戶(hù)的IM架構(gòu)技術(shù)干貨(上篇):整體架構(gòu)、服務(wù)拆分等

          一套億級(jí)用戶(hù)的IM架構(gòu)技術(shù)干貨(下篇):可靠性、有序性、弱網(wǎng)優(yōu)化等》(本文)

          本篇主要聚焦這套億級(jí)用戶(hù)的IM架構(gòu)的一些比較細(xì)節(jié)但很重要的熱門(mén)問(wèn)題上。

          3、消息可靠性問(wèn)題

          消息的可靠性是IM系統(tǒng)的典型技術(shù)指標(biāo),對(duì)于用戶(hù)來(lái)說(shuō),消息能不能被可靠送達(dá)(不丟消息),是使用這套IM的信任前提。

          換句話說(shuō),如果這套IM系統(tǒng)不能保證不丟消息,那相當(dāng)于發(fā)送的每一條消息都有被丟失的概率,對(duì)于用戶(hù)而言,一定會(huì)不會(huì)“放心”地使用它,即“不信任”這套IM。

          從產(chǎn)品經(jīng)理的角度來(lái)說(shuō),有這樣的技術(shù)障礙存在,再怎么費(fèi)力的推廣,最終用戶(hù)都會(huì)很快流失。所以一套IM如果不能保證消息的可靠性,那問(wèn)題是很?chē)?yán)重的。

          PS:如果你對(duì)IM消息可靠性的問(wèn)題還沒(méi)有一個(gè)直觀的映象的話,通過(guò)《零基礎(chǔ)IM開(kāi)發(fā)入門(mén)(三):什么是IM系統(tǒng)的可靠性?》這篇文章可以通俗易懂的理解它。

          如上圖所示,消息可靠性主要依賴(lài)2個(gè)邏輯來(lái)保障:

          • 1)上行消息可靠性;
          • 2)下行消息可靠性。

          1)針對(duì)上行消息的可靠性,可以這樣的思路來(lái)處理:

          用戶(hù)發(fā)送一個(gè)消息(假設(shè)協(xié)議叫PIMSendReq),用戶(hù)要給這個(gè)消息設(shè)定一個(gè)本地ID,然后等待服務(wù)器操作完成給發(fā)送者一個(gè)PIMSendAck(本地ID一致),告訴用戶(hù)發(fā)送成功了。

          如果等待一段時(shí)間,沒(méi)收到這個(gè)ACK,說(shuō)明用戶(hù)發(fā)送不成功,客戶(hù)端SDK要做重試操作。

          2)針對(duì)下行消息的可靠性,可以這樣的思路來(lái)處理:

          服務(wù)收到了用戶(hù)A的消息,要把這個(gè)消息推送給B、C、D 3個(gè)人。假設(shè)B臨時(shí)掉線了,那么在線推送很可能會(huì)失敗。

          因此確保下行可靠性的核心是:在做推送前要把這個(gè)推送請(qǐng)求緩存起來(lái)。

          這個(gè)緩存由存儲(chǔ)系統(tǒng)來(lái)保證,MsgWriter要維護(hù)一個(gè)(離線消息列表),用戶(hù)的一條消息,要同時(shí)寫(xiě)入B、C、D的離線消息列表,B、C、D收到這個(gè)消息以后,要給存儲(chǔ)系統(tǒng)一個(gè)ACK,然后存儲(chǔ)系統(tǒng)把消息ID從離線消息列表里拿掉。

          針對(duì)消息的可靠性問(wèn)題,具體的解決思路還可以從另一個(gè)維度來(lái)考慮:即實(shí)時(shí)消息的可靠性和離線消息的可靠性。

          有興趣可以深入讀一讀這兩篇:

          IM消息送達(dá)保證機(jī)制實(shí)現(xiàn)(一):保證在線實(shí)時(shí)消息的可靠投遞

          IM消息送達(dá)保證機(jī)制實(shí)現(xiàn)(二):保證離線消息的可靠投遞

          而對(duì)于離線消息的可靠性來(lái)說(shuō),單聊和群聊又有很大區(qū)別,有關(guān)群聊的離線消息可靠投遞問(wèn)題,可以深入讀一讀《IM開(kāi)發(fā)干貨分享:如何優(yōu)雅的實(shí)現(xiàn)大量離線消息的可靠投遞》。

          4、消息有序性問(wèn)題

          消息的有序性問(wèn)題是分布式IM系統(tǒng)中的另一個(gè)技術(shù)“硬骨頭”。

          因?yàn)槭欠植际较到y(tǒng),客戶(hù)端和服務(wù)器的時(shí)鐘可能是不同步的。如果簡(jiǎn)單依賴(lài)某一方的時(shí)鐘,就會(huì)出現(xiàn)大量的消息亂序。

          比如只依賴(lài)客戶(hù)端的時(shí)鐘,A比B時(shí)間晚30分鐘。所有A給B發(fā)消息,然后B給A回復(fù)。

          發(fā)送順序是:

          客戶(hù)端A:“XXX”

          客戶(hù)端B:“YYY”

          接收方的排序就會(huì)變成:

          客戶(hù)端B:“YYY”

          客戶(hù)端A:“XXX”

          因?yàn)锳的時(shí)間晚30分鐘,所有A的消息都會(huì)排在后面。

          如果只依賴(lài)服務(wù)器的時(shí)鐘,也會(huì)出現(xiàn)類(lèi)似的問(wèn)題,因?yàn)?個(gè)服務(wù)器時(shí)間可能也不一致。雖然客戶(hù)端A和客戶(hù)端B時(shí)鐘一致,但是A的消息由服務(wù)器S1處理,B的消息由服務(wù)器S2處理,也會(huì)導(dǎo)致同樣消息亂序。

          為了解決這種問(wèn)題,我的思路是通過(guò)可以做這樣一系列的操作來(lái)實(shí)現(xiàn)。

          1)服務(wù)器時(shí)間對(duì)齊:

          這部分就是后端運(yùn)維的鍋了,由系統(tǒng)管理員來(lái)盡量保障,沒(méi)有別的招兒。

          2)客戶(hù)端通過(guò)時(shí)間調(diào)校對(duì)齊服務(wù)器時(shí)間:

          比如:客戶(hù)端登錄以后,拿客戶(hù)端時(shí)間和服務(wù)器時(shí)間做差值計(jì)算,發(fā)送消息的時(shí)候考慮這部分差值。

          在我的im架構(gòu)里,這個(gè)能把時(shí)間對(duì)齊到100ms這個(gè)級(jí),差值再小的話就很困難了,因?yàn)閰f(xié)議在客戶(hù)端和服務(wù)器之間傳遞速度RTT也是不穩(wěn)定的(網(wǎng)絡(luò)傳輸存在不可控的延遲風(fēng)險(xiǎn)嘛)。

          3)消息同時(shí)帶上本地時(shí)間和服務(wù)器時(shí)間:

          具體可以這樣的處理:排序的時(shí)候,對(duì)于同一個(gè)人的消息,按照消息本地時(shí)間來(lái)排;對(duì)于不同人的消息,按照服務(wù)器時(shí)間來(lái)排,這是插值排序算法。

          PS:關(guān)于消息有序性的問(wèn)題,顯然也不是上面這三兩句話能講的清楚,如果你想更通俗一理解它,可以讀一讀《零基礎(chǔ)IM開(kāi)發(fā)入門(mén)(四):什么是IM系統(tǒng)的消息時(shí)序一致性?》。

          另外:從技術(shù)實(shí)踐可行性的角度來(lái)說(shuō),《一個(gè)低成本確保IM消息時(shí)序的方法探討》、《如何保證IM實(shí)時(shí)消息的“時(shí)序性”與“一致性”?》這兩篇中的思路可以借鑒一下。

          實(shí)際上,消息的排序問(wèn)題,還可以從消息ID的角度去處理(也就是通過(guò)算法讓消息ID產(chǎn)生順序性,從而根據(jù)消息ID就能達(dá)到消息排序的目的)。

          有關(guān)順序的消息ID算法問(wèn)題,這兩篇非常值得借鑒:IM消息ID技術(shù)專(zhuān)題(一):微信的海量IM聊天消息序列號(hào)生成實(shí)踐(算法原理篇)》、《IM消息ID技術(shù)專(zhuān)題(三):解密融云IM產(chǎn)品的聊天消息ID生成策略》,我就不廢話了。

          5、消息已讀同步問(wèn)題

          消息的已讀未讀功能,如下圖所示: 

          上圖就是釘釘中的已讀未讀消息。這在企業(yè)IM場(chǎng)景下非常有用(因?yàn)樽鲱I(lǐng)導(dǎo)的都喜歡,你懂的)。

          已讀未讀功能,對(duì)于一對(duì)一的單聊消息來(lái)說(shuō),還比較好理解:就是多加一條對(duì)應(yīng)的回執(zhí)息(當(dāng)用戶(hù)閱讀這條消息時(shí)發(fā)回)。

          但對(duì)于群聊這說(shuō),這一條消息有多少人已讀、多少人未讀,想實(shí)現(xiàn)這個(gè)效果,那就真的有點(diǎn)麻煩了。對(duì)于群聊的已讀未讀功能實(shí)現(xiàn)邏輯,這里就不展開(kāi)了,有興趣可以讀一下這篇《IM群聊消息的已讀回執(zhí)功能該怎么實(shí)現(xiàn)?》。

          回歸到本節(jié)的主題“已讀同步”的問(wèn)題,這顯示難度又進(jìn)一級(jí),因?yàn)橐炎x未讀回執(zhí)不只是針對(duì)“賬號(hào)”,現(xiàn)在還要細(xì)分到“同一賬號(hào)在不同端登陸”的情況,對(duì)于已讀回執(zhí)的同步邏輯來(lái)說(shuō),這就有點(diǎn)復(fù)雜化了。

          在這里,根據(jù)我這邊IM架構(gòu)的實(shí)踐經(jīng)驗(yàn),提供一些思路。

          具體來(lái)說(shuō)就是:用戶(hù)可能有多個(gè)設(shè)備登錄同一個(gè)賬戶(hù)(比如:Web PC和移動(dòng)端同時(shí)登陸),這種情況下的已讀未讀功能,就需要來(lái)實(shí)現(xiàn)已讀同步,否則在設(shè)備1看過(guò)的消息,設(shè)備2看到依然是未讀消息,從產(chǎn)品的角度來(lái)說(shuō),這就影響用戶(hù)體驗(yàn)了。

          對(duì)于我的im架構(gòu)來(lái)說(shuō),已讀同步主要依賴(lài)2個(gè)邏輯來(lái)保證:

          • 1)同步狀態(tài)維護(hù),為用戶(hù)的每一個(gè)Session,維護(hù)一個(gè)時(shí)間戳,保存最后的讀消息時(shí)間;
          • 2)如果用戶(hù)打開(kāi)了某個(gè)Session,且用戶(hù)有多個(gè)設(shè)備在線,發(fā)送一條PIMSyncRead消息,通知其它設(shè)備。

          6、數(shù)據(jù)安全問(wèn)題

          6.1 基礎(chǔ)

          IM系統(tǒng)架構(gòu)中的數(shù)據(jù)安全比一般系統(tǒng)要復(fù)雜一些,從通信的角度來(lái)說(shuō),它涉及到socket長(zhǎng)連接通信的安全性和http短連接的兩重安全性。而隨著IM在移動(dòng)端的流行,又要在安全性、性能、數(shù)據(jù)流量、用戶(hù)體驗(yàn)這幾個(gè)維度上做權(quán)衡,所以想要實(shí)現(xiàn)一套完善的IM安全架構(gòu),要面臨的挑戰(zhàn)是很多的。

          IM系統(tǒng)架構(gòu)中,所謂的數(shù)據(jù)安全,主要是通信安全和內(nèi)容安全。

          6.2 通信安全

          所謂的通信安全,這就要理解IM通信的服務(wù)組成。

          目前來(lái)說(shuō),一個(gè)典型的im系統(tǒng),主要由兩種通信服務(wù)組成:

          • 1)socket長(zhǎng)連接服務(wù):技術(shù)上也就是多數(shù)人耳熟能詳?shù)木W(wǎng)絡(luò)通信這一塊,再細(xì)化一點(diǎn)也就是tcp、udp協(xié)議這一塊;
          • 2)http短連接服務(wù):也就是最常用的http rest接口那些。

          對(duì)于提升長(zhǎng)連接的安全性思路,可以深入閱讀《通俗易懂:一篇掌握即時(shí)通訊的消息傳輸安全原理》。另外,微信團(tuán)隊(duì)分享的《微信新一代通信安全解決方案:基于TLS1.3的MMTLS詳解》一文,也非常有參考意義。

          如果是通信安全級(jí)別更高的場(chǎng)景,可以參考《即時(shí)通訊安全篇(二):探討組合加密算法在IM中的應(yīng)用》,文中關(guān)于組合加密算法的使用思路非常不錯(cuò)。

          至于短連接安全性,大家就很熟悉了,開(kāi)啟https多數(shù)情況下就夠用了。如果對(duì)于https不甚了解,可以從這幾篇開(kāi)始:《一文讀懂Https的安全性原理、數(shù)字證書(shū)、單項(xiàng)認(rèn)證、雙項(xiàng)認(rèn)證等》、《即時(shí)通訊安全篇(七):如果這樣來(lái)理解HTTPS,一篇就夠了》。

          6.3 內(nèi)容安全

          這個(gè)可能不太好理解,上面既然實(shí)現(xiàn)了通信安全,那為什么還要糾結(jié)“內(nèi)容安全”?

          我們了解一下所謂的密碼學(xué)三大作用:加密( Encryption)、認(rèn)證(Authentication),鑒定(Identification) 。

          詳細(xì)來(lái)說(shuō)就是:

          加密:防止壞人獲取你的數(shù)據(jù)。

          認(rèn)證:防止壞人修改了你的數(shù)據(jù)而你卻并沒(méi)有發(fā)現(xiàn)。

          鑒權(quán):防止壞人假冒你的身份。

          在上節(jié)中,惡意攻擊者如果在通信環(huán)節(jié)繞開(kāi)或突破了“鑒權(quán)”、“認(rèn)證”,那么依賴(lài)于“鑒權(quán)”、“認(rèn)證”的“加密”,實(shí)際上也有可有被破解。

          針對(duì)上述問(wèn)題,那么我們需要對(duì)內(nèi)容進(jìn)行更加安全獨(dú)立的加密處理,就這是所謂的“端到端加密”(E2E)。

          比如,那個(gè)號(hào)稱(chēng)無(wú)法被破解的IM——Telegram,實(shí)際上就是使用了端到端加密技術(shù)。

          關(guān)于端到端加密,這里就不深入探討,這里有兩篇文章有興趣地可以深入閱讀:

          移動(dòng)端安全通信的利器——端到端加密(E2EE)技術(shù)詳解

          簡(jiǎn)述實(shí)時(shí)音視頻聊天中端到端加密(E2EE)的工作原理

          7、雪崩效應(yīng)問(wèn)題

          在分布式的IM架構(gòu)中,存在雪崩效應(yīng)問(wèn)題。

          我們知道,分布式的IM架構(gòu)中,為了高可用性,用戶(hù)每次登陸都是根據(jù)負(fù)載均衡算法分配到不同的服務(wù)器。那么問(wèn)題就來(lái)了。

          舉個(gè)例子:假設(shè)有5個(gè)機(jī)房,其中A機(jī)房故障,導(dǎo)致這個(gè)機(jī)房先前服務(wù)的用戶(hù)都跑去B機(jī)房。B機(jī)房不堪重負(fù)也崩潰了,A+B的用戶(hù)跑去機(jī)房C,連鎖反應(yīng)會(huì)導(dǎo)致所有服務(wù)掛掉。

          防止雪崩效應(yīng)需要在服務(wù)器架構(gòu),客戶(hù)端鏈接策略上有一些配合的解決方案。服務(wù)器需要有限流能力作為基礎(chǔ),主要是限制總服務(wù)用戶(hù)數(shù)和短時(shí)間鏈接用戶(hù)數(shù)。

          在客戶(hù)端層面,發(fā)現(xiàn)服務(wù)斷開(kāi)之后要有一個(gè)策略,防止大量用戶(hù)同一時(shí)間去鏈接某個(gè)服務(wù)器。

          通常有2種方案:

          • 1)退避:重連之間設(shè)置一個(gè)隨機(jī)的間隔;
          • 2)LBS:跟服務(wù)器申請(qǐng)重連的新的服務(wù)器IP,然后由LBS服務(wù)去降低短時(shí)間分配到同一個(gè)服務(wù)器的用戶(hù)量。

          這2種方案互不沖突,可以同時(shí)做。

          8、弱網(wǎng)問(wèn)題

          8.1 弱網(wǎng)問(wèn)題的原因

          鑒于如今IM在移動(dòng)端的流行,弱網(wǎng)是很常態(tài)的問(wèn)題。電梯、火車(chē)上、開(kāi)車(chē)、地鐵等等場(chǎng)景,都會(huì)遇到明顯的弱網(wǎng)問(wèn)題。

          那么為什么會(huì)出現(xiàn)弱網(wǎng)問(wèn)題?

          要回答這個(gè)問(wèn)題,那就需要從無(wú)線通信的原理上去尋找答案。

          因?yàn)闊o(wú)線通信的質(zhì)量受制于很多方面的因素,比如:無(wú)線信號(hào)強(qiáng)弱變化快、信號(hào)干擾、通信基站分布不均、移動(dòng)速度太快等等。要說(shuō)清楚這個(gè)問(wèn)題,那就真是三天三夜都講不完。

          有興趣的讀者,一定要仔細(xì)閱讀下面這幾篇文章,類(lèi)似的跨學(xué)科科譜式文章并不多見(jiàn):

          IM開(kāi)發(fā)者的零基礎(chǔ)通信技術(shù)入門(mén)(十一):為什么WiFi信號(hào)差?一文即懂!

          IM開(kāi)發(fā)者的零基礎(chǔ)通信技術(shù)入門(mén)(十二):上網(wǎng)卡頓?網(wǎng)絡(luò)掉線?一文即懂!

          IM開(kāi)發(fā)者的零基礎(chǔ)通信技術(shù)入門(mén)(十三):為什么手機(jī)信號(hào)差?一文即懂!

          IM開(kāi)發(fā)者的零基礎(chǔ)通信技術(shù)入門(mén)(十四):高鐵上無(wú)線上網(wǎng)有多難?一文即懂!

          弱網(wǎng)問(wèn)題是移動(dòng)端APP的必修課,下面這幾篇總結(jié)也值得借鑒:

          移動(dòng)端IM開(kāi)發(fā)者必讀(一):通俗易懂,理解移動(dòng)網(wǎng)絡(luò)的“弱”和“慢”

          移動(dòng)端IM開(kāi)發(fā)者必讀(二):史上最全移動(dòng)弱網(wǎng)絡(luò)優(yōu)化方法總結(jié)

          現(xiàn)代移動(dòng)端網(wǎng)絡(luò)短連接的優(yōu)化手段總結(jié):請(qǐng)求速度、弱網(wǎng)適應(yīng)、安全保障

          百度APP移動(dòng)端網(wǎng)絡(luò)深度優(yōu)化實(shí)踐分享(三):移動(dòng)端弱網(wǎng)優(yōu)化篇

          8.2 IM針對(duì)弱網(wǎng)問(wèn)題的處理

          對(duì)于IM來(lái)說(shuō),弱網(wǎng)問(wèn)題并不是很復(fù)雜,核心是做好消息的重發(fā)、排序以及接收端的重試。

          為了解決好弱網(wǎng)引發(fā)的IM問(wèn)題,通常可以通過(guò)以下手段改善:

          • 1)消息自動(dòng)重發(fā);
          • 2)離線消息接收;
          • 3)重發(fā)消息排序;
          • 4)離線指令處理。

          下面將逐一展開(kāi)討論。

          8.3 消息自動(dòng)重發(fā)

          坐地鐵的時(shí)候,經(jīng)常遇到列車(chē)開(kāi)起來(lái)以后,網(wǎng)絡(luò)斷開(kāi),發(fā)送消息失敗。

          這時(shí)候產(chǎn)品有2種表現(xiàn)形式:

          • a、直接告訴用戶(hù)發(fā)送失敗;
          • b、保持發(fā)送狀態(tài),自動(dòng)重試3-5次(3分鐘)以后告訴用戶(hù)發(fā)送失敗。

          顯然:自動(dòng)重試失敗以后再告訴用戶(hù)發(fā)送失敗體驗(yàn)要好很多。尤其是在網(wǎng)絡(luò)閃斷情況下,重試成功率很高,很可能用戶(hù)根本感知不到有發(fā)送失敗。

          從技術(shù)上:客戶(hù)端IMSDK要把每條消息的狀態(tài)監(jiān)控起來(lái)。發(fā)送消息不能簡(jiǎn)單的調(diào)用一下網(wǎng)絡(luò)發(fā)送請(qǐng)求,而是要有一個(gè)狀態(tài)機(jī),管理幾個(gè)狀態(tài):初始狀態(tài),發(fā)送中,發(fā)送失敗,發(fā)送超時(shí)。對(duì)于失敗和超時(shí)的狀態(tài),要啟用重試機(jī)制。

          這里還有一篇關(guān)于重試機(jī)制設(shè)計(jì)的討論帖子,有興趣可以看看:完全自已開(kāi)發(fā)的IM該如何設(shè)計(jì)“失敗重試”機(jī)制?》。

          IM消息送達(dá)保證機(jī)制實(shí)現(xiàn)(一):保證在線實(shí)時(shí)消息的可靠投遞》一文中關(guān)于消息超時(shí)與重傳機(jī)制的實(shí)現(xiàn)思路,也可以參考一下。

          8.4 離線消息接收

          現(xiàn)代IM是沒(méi)有“在線”這個(gè)狀態(tài)的,不需要給用戶(hù)這個(gè)信息。但是從技術(shù)的層面,用戶(hù)掉線了還是要正確的去感知的。

          感知方法有幾條:

          • a、信令長(zhǎng)連接狀態(tài):如果長(zhǎng)時(shí)間沒(méi)收到到服務(wù)器的心跳反饋,說(shuō)明掉線了;
          • b、網(wǎng)絡(luò)請(qǐng)求失敗次數(shù):如果多次網(wǎng)絡(luò)請(qǐng)求失敗,說(shuō)明”可能“掉線了;
          • c、設(shè)備網(wǎng)絡(luò)狀態(tài)檢測(cè):直接檢測(cè)網(wǎng)卡狀態(tài)就好,一般Android/iOS/Windows/Mac都有相應(yīng)系統(tǒng)API。

          正確檢測(cè)到網(wǎng)絡(luò)狀態(tài)以后,發(fā)現(xiàn)網(wǎng)絡(luò)從”斷開(kāi)到恢復(fù)“的切換,要去主動(dòng)拉取離線階段的消息,就可以做到弱網(wǎng)狀態(tài)不丟消息(從服務(wù)器的離線消息列表拉取)。

          上面文字中提到的網(wǎng)絡(luò)狀態(tài)的確定,涉及到IM里網(wǎng)絡(luò)連接檢查和保活機(jī)制問(wèn)題,是IM里比較頭疼的問(wèn)題。

          一不小心,又踩進(jìn)了IM網(wǎng)絡(luò)保活這個(gè)坑,我就不在這里展開(kāi),有興趣一定要讀讀下面的文章:

          為何基于TCP協(xié)議的移動(dòng)端IM仍然需要心跳保活機(jī)制?

          一文讀懂即時(shí)通訊應(yīng)用中的網(wǎng)絡(luò)心跳包機(jī)制:作用、原理、實(shí)現(xiàn)思路等

          微信團(tuán)隊(duì)原創(chuàng)分享:Android版微信后臺(tái)保活實(shí)戰(zhàn)分享(網(wǎng)絡(luò)保活篇)

          移動(dòng)端IM實(shí)踐:實(shí)現(xiàn)Android版微信的智能心跳機(jī)制

          移動(dòng)端IM實(shí)踐:WhatsApp、Line、微信的心跳策略分析

          8.5 重發(fā)消息排序

          弱網(wǎng)邏輯的另一個(gè)坑是消息排序。

          假如有A、B、C  3條消息,A、C發(fā)送成功,B發(fā)送的時(shí)候遇到了網(wǎng)絡(luò)閃斷,B觸發(fā)自動(dòng)重試。

          那么接收方的接收順序應(yīng)該是 A B C還是A C B呢?我觀察過(guò)不同的IM產(chǎn)品,處理邏輯各不相同,這個(gè)大家有興趣可以去玩一下。

          這個(gè)解決方法是要依賴(lài)上一篇服務(wù)架構(gòu)里提到的差值排序,同一個(gè)人發(fā)出的消息,排序按消息附帶的本地時(shí)間來(lái)排。不同人的消息,按照服務(wù)器時(shí)間排序。

          具體我這邊就不再得復(fù),可以回頭看看本篇中的第四節(jié)“4、消息有序性問(wèn)題”。

          8.6 離線指令處理

          部分指令操作的時(shí)候,網(wǎng)絡(luò)可能出現(xiàn)了問(wèn)題,等網(wǎng)絡(luò)恢復(fù)以后,要自動(dòng)同步給服務(wù)器。

          舉一個(gè)例子,大家可以試試手機(jī)設(shè)置為飛行模式,然后在微信里刪除一個(gè)聯(lián)系人,看看能不能刪除。然后重新打開(kāi)網(wǎng)絡(luò),看看這個(gè)數(shù)據(jù)會(huì)不會(huì)同步到服務(wù)器。

          類(lèi)似的邏輯也適用于已讀同步等場(chǎng)景,離線狀態(tài)看過(guò)的信息,要正確的跟服務(wù)器同步。

          8.7 小結(jié)一下

          IM的弱網(wǎng)處理,其實(shí)相對(duì)還是比較簡(jiǎn)單的,基本上自動(dòng)重試+消息狀態(tài)就可以解決絕大部分的問(wèn)題了。

          一些細(xì)節(jié)處理也并不復(fù)雜,主要原因是IM的消息量比較小,網(wǎng)絡(luò)恢復(fù)后能快速的恢復(fù)操作。

          視頻會(huì)議在弱網(wǎng)下的邏輯,就要復(fù)雜的多了。尤其是高丟包的弱網(wǎng)環(huán)境下,要盡力去保證音視頻的流暢性。

          9、本文小結(jié)

          《一套億級(jí)用戶(hù)的IM架構(gòu)技術(shù)干貨》這期文章的上下兩篇就這么侃完了,上篇涉及到的IM架構(gòu)問(wèn)題倒還好,下篇一不小心又帶出了IM里的各種熱門(mén)問(wèn)題“坑”,搞IM開(kāi)發(fā)直是一言難盡。。。

          建議IM開(kāi)發(fā)的入門(mén)朋友們,如果想要系統(tǒng)地學(xué)習(xí)移動(dòng)端IM開(kāi)發(fā)的話,應(yīng)該去讀一讀我整理的那篇IM開(kāi)發(fā)“從入門(mén)到放棄”的文章(哈哈哈),就是這篇《新手入門(mén)一篇就夠:從零開(kāi)發(fā)移動(dòng)端IM》。具體我就不再展開(kāi)了,不然這篇幅又要?jiǎng)x不住車(chē)了。。。

          10、參考資料

          [1] 大規(guī)模并發(fā)IM服務(wù)架構(gòu)設(shè)計(jì)

          [2] IM的弱網(wǎng)場(chǎng)景優(yōu)化

          [3] 零基礎(chǔ)IM開(kāi)發(fā)入門(mén)(三):什么是IM系統(tǒng)的可靠性?

          [4] IM消息送達(dá)保證機(jī)制實(shí)現(xiàn)(一):保證在線實(shí)時(shí)消息的可靠投遞

          [5] IM開(kāi)發(fā)干貨分享:如何優(yōu)雅的實(shí)現(xiàn)大量離線消息的可靠投遞

          [6] 即時(shí)通訊安全篇(二):探討組合加密算法在IM中的應(yīng)用

          [7] 微信新一代通信安全解決方案:基于TLS1.3的MMTLS詳解

          附錄:更多IM開(kāi)發(fā)文章匯總

          零基礎(chǔ)IM開(kāi)發(fā)入門(mén)(一):什么是IM系統(tǒng)?

          零基礎(chǔ)IM開(kāi)發(fā)入門(mén)(二):什么是IM系統(tǒng)的實(shí)時(shí)性?

          IM開(kāi)發(fā)干貨分享:如何優(yōu)雅的實(shí)現(xiàn)大量離線消息的可靠投遞

          IM開(kāi)發(fā)干貨分享:有贊移動(dòng)端IM的組件化SDK架構(gòu)設(shè)計(jì)實(shí)踐

          IM開(kāi)發(fā)寶典:史上最全,微信各種功能參數(shù)和邏輯規(guī)則資料匯總

          IM開(kāi)發(fā)干貨分享:我是如何解決大量離線消息導(dǎo)致客戶(hù)端卡頓的

          從客戶(hù)端的角度來(lái)談?wù)勔苿?dòng)端IM的消息可靠性和送達(dá)機(jī)制

          騰訊技術(shù)分享:社交網(wǎng)絡(luò)圖片的帶寬壓縮技術(shù)演進(jìn)之路

          移動(dòng)端IM中大規(guī)模群消息的推送如何保證效率、實(shí)時(shí)性?

          移動(dòng)端IM開(kāi)發(fā)需要面對(duì)的技術(shù)問(wèn)題

          開(kāi)發(fā)IM是自己設(shè)計(jì)協(xié)議用字節(jié)流好還是字符流好?

          請(qǐng)問(wèn)有人知道語(yǔ)音留言聊天的主流實(shí)現(xiàn)方式嗎?

          IM單聊和群聊中的在線狀態(tài)同步應(yīng)該用“推”還是“拉”?

          IM群聊消息如此復(fù)雜,如何保證不丟不重?

          談?wù)勔苿?dòng)端 IM 開(kāi)發(fā)中登錄請(qǐng)求的優(yōu)化

          移動(dòng)端IM登錄時(shí)拉取數(shù)據(jù)如何作到省流量?

          通俗易懂:基于集群的移動(dòng)端IM接入層負(fù)載均衡方案分享

          微信對(duì)網(wǎng)絡(luò)影響的技術(shù)試驗(yàn)及分析(論文全文)

          本文已同步發(fā)布于“即時(shí)通訊技術(shù)圈”公眾號(hào)。

          ▲ 本文在公眾號(hào)上的鏈接是:點(diǎn)此進(jìn)入。同步發(fā)布鏈接是:http://www.52im.net/thread-3445-1-1.html



          作者:Jack Jiang (點(diǎn)擊作者姓名進(jìn)入Github)
          出處:http://www.52im.net/space-uid-1.html
          交流:歡迎加入即時(shí)通訊開(kāi)發(fā)交流群 215891622
          討論:http://www.52im.net/
          Jack Jiang同時(shí)是【原創(chuàng)Java Swing外觀工程BeautyEye】【輕量級(jí)移動(dòng)端即時(shí)通訊框架MobileIMSDK】的作者,可前往下載交流。
          本博文 歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處(也可前往 我的52im.net 找到我)。


          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          Jack Jiang的 Mail: jb2011@163.com, 聯(lián)系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 建湖县| 萨嘎县| 河津市| 馆陶县| 达州市| 长兴县| 太仆寺旗| 改则县| 杭锦后旗| 八宿县| 香港| 房山区| 福鼎市| 姜堰市| 荔浦县| 讷河市| 大丰市| 仪征市| 资溪县| 菏泽市| 江陵县| 衡阳县| 阳东县| 武穴市| 兴化市| 彩票| 盐源县| 巴中市| 田东县| 鹤岗市| 湄潭县| 雷州市| 射阳县| 华阴市| 抚州市| 邻水| 潞城市| 德保县| 策勒县| 阜宁县| 灵丘县|