<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Jack Jiang

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

    本文引用了沈劍《如何保證IM實時消息的“時序性”與“一致性”?》一文的圖片和內容(由于太懶,圖沒重新畫),原文鏈接在文末。

    1、引言

    本文接上篇《零基礎IM開發(fā)入門(三):什么是IM系統(tǒng)的可靠性?》,講解IM系統(tǒng)中消息時序的一致性問題。

    所謂的一致性,在IM中通常指的是消息時序的一致性,那就是:

    • 1)聊天消息的上下文連續(xù)性;
    • 2)聊天消息的絕對時間序。

    再具體一點,IM消息的一致性體現(xiàn)在:

    • 1)單聊時:要保證發(fā)送方發(fā)出聊天消息的順序與接收方看到的順序一致;
    • 2)群聊時:要保證所有群員看到的聊天消息,與發(fā)送者發(fā)出消息時的絕對時間序是一致的。

    IM系統(tǒng)中消息時序的一致性問題是個看似簡單,實則非常有難度的技術熱點話題之一,本文盡量以通俗簡顯的文字為你講解IM消息時序一致性問題的產品意義、發(fā)生原因、解決思路等

    • 學習交流:

    - 即時通訊/推送技術開發(fā)交流5群:215477170 [推薦]

    - 移動端IM開發(fā)入門文章:《新手入門一篇就夠:從零開發(fā)移動端IM

    - 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK

    (本文同步發(fā)布于:http://www.52im.net/thread-3189-1-1.html

    2、系列文章

    零基礎IM開發(fā)入門(一):什么是IM系統(tǒng)?

    零基礎IM開發(fā)入門(二):什么是IM系統(tǒng)的實時性?

    零基礎IM開發(fā)入門(三):什么是IM系統(tǒng)的可靠性?

    零基礎IM開發(fā)入門(四):什么是IM系統(tǒng)的消息時序一致性?》(* 本文

    《零基礎IM開發(fā)入門(五):什么是IM系統(tǒng)的安全性? (稍后發(fā)布)》

    《零基礎IM開發(fā)入門(六):什么是IM系統(tǒng)的的心跳機制? (稍后發(fā)布)》

    《零基礎IM開發(fā)入門(七):如何理解并實現(xiàn)IM系統(tǒng)消息未讀數(shù)? (稍后發(fā)布)》

    《零基礎IM開發(fā)入門(八):如何理解并實現(xiàn)IM系統(tǒng)的多端消息漫游? (稍后發(fā)布)》

    3、消息時序的一致性,對于IM的意義

    現(xiàn)如今,由于移動互聯(lián)網的普及,現(xiàn)代人的實際社交關系,幾乎完全是靠IM這種即時通訊社交工具所組織起來的,IM這種工具的重要性不言而喻。

    IM在現(xiàn)代人的生活中,越來越重要,但也越來平常。現(xiàn)在想聯(lián)系一個人,第一時間想到的不是打個電話,而是發(fā)個“微信”或“QQ”。是的,IM這玩意承載的意義越來越多。

    消息時序的一致性問題,對于IM的意義,毫無疑問帶來的不只是簡簡單單的所謂用戶體驗問題。我們來看看例子。

    假設:你跟女神的表白正進入到關鍵階段,聊著聊著就因為這爛IM,導致聊天消息前言不搭后語,此刻1000公里外你的女神真一臉蒙逼的盯著手機看你的“醉話”,后果是多么嚴重——這半年來的“舔狗”生活、忍辱負重,算是白白被程序員這群“格子衫”、“地中海”們給禍害了。

    再往嚴重了說,就因為這爛IM,讓你失去了這難得的借助女神優(yōu)良基因,改造家族后代顏值的絕佳機會,無不讓人痛心疾首。。。

    上面這個例子,說的還只是單聊,如果是群聊,則問題可能還會被無限放大:試想一個技術交流群,正在激烈的爭吵著“php是世界最好語言”這種話題的時候,忽然就想砸手機了,不是因為吵的太兇,而因為消息順序全亂完全沒法看,已經嚴重影響鍵盤俠們積極發(fā)表個人意見了。

    4、憑什么說保證消息時序的一致性很困難?

    4.1 基本認知

    在普通IM用戶的眼里,消息無非是從一臺手機傳遞到另一臺手機而已,保證時序有何困難?

    是的,普通用戶這么認為,從技術上講,他只是單純的將IM消息的收發(fā)過程理解為單線程的工作模式而已。

    實際上,在IM這種高性能場景下,服務端為了追求高吞吐、高并發(fā),用到了多線程、異步IO等等技術。

    在這種情況下,“高并發(fā)”與“順序”對于IM服務端來說,本來就是矛盾的,這就有點魚與熊掌的味道了(兩者很難兼得)。

    所以,要實現(xiàn)IM場景下的消息時序一致性,需要做出權衡,而且要考慮的技術維度相當多。這就導致具體技術實施起來沒有固定的套路,而由于開發(fā)者技術能力的參差不齊,也就使得很多IM系統(tǒng)在實際的效果上會有較大問題,對于用戶而言也將直接在產品體驗上反應出來。

    下面將具體說明技術難點所在。

    4.2 沒有全局時鐘

    如上圖所示,一個真正堪用的生產系統(tǒng),顯示不可能所有服務都跑在一臺服務器上,分布式環(huán)境是肯定的。

    那么:在分布式環(huán)境下,客戶端+服務端后臺的各種后臺服務,都各自分布在不同的機器上,機器之間都是使用的本地時鐘,沒有一個所謂的“全局時鐘”(也沒辦法做到真正的全局時鐘),那么所謂的消息時序也就沒有真正意義上的時序基準點。所以消息時序問題顯然不是“本地時間”可以完全決定的。

    4.3 多發(fā)送方問題

    服務端分布式的情況下,不能用“本地時間”來保證時序性,那么能否用接收方本地時間表示時序呢?

    遺憾的是,由于多個客戶端的存在(比如群聊時),即使是一臺服務器的本地時間,也無法表示“絕對時序”。

    如上圖所示:絕對時序上,APP1先發(fā)出msg1,APP2后發(fā)出msg2,都發(fā)往服務器web1,網絡傳輸是不能保證msg1一定先于msg2到達的,所以即使以一臺服務器web1的時間為準,也不能精準描述msg1與msg2的絕對時序。

    4.4 多接收方問題

    多發(fā)送方不能保證時序,假設只有一個發(fā)送方,能否用發(fā)送方的本地時間表示時序呢?遺憾的是,由于多個接收方的存在,無法用發(fā)送方的本地時間,表示“絕對時序”。

    如上圖,絕對時序上,web1先發(fā)出msg1,后發(fā)出msg2,由于網絡傳輸及多接收方的存在,無法保證msg1先被接收到先被處理,故也無法保證msg1與msg2的處理時序。

    4.5 網絡傳輸與多線程問題

    既然多發(fā)送方與多接收方都難以保證絕對時序,那么假設只有單一的發(fā)送方與單一的接收方,能否保證消息的絕對時序一致性呢?

    結論是悲觀的,由于網絡傳輸與多線程的存在,這仍然不行。

    如上圖所示,web1先發(fā)出msg1、后發(fā)出msg2,即使msg1先到達(網絡傳輸其實還不能保證msg1先到達),由于多線程的存在,也不能保證msg1先被處理完。

    5、如何保證絕對的消息時序一致性?

    通過上一章內容的總結,我們已經對IM中消息時序一致性問題所產生的緣由,有了較為深刻的認識。

    從純技術的角度來說,假設:

    • 1)只有一個發(fā)送方;
    • 2)一個接收方;
    • 3)上下游連接只有一條socket連接;
    • 4)通過阻塞的方式通訊。

    這樣的情況下,難道不能保證先發(fā)出的消息被先處理,進而被先展示給消息的接收者嗎?

    是的,可以!

    但實際生產情況下不太可能出現(xiàn)這種IM系統(tǒng),必竟單發(fā)送方、單接收方、單socket連接、阻塞方式,這樣的IM一旦做出來,產品經理會立馬死給你看。。。

    6、實用的優(yōu)化思路

    6.1 一對一單聊的消息一致性保證思路

    假設兩人一對一聊天,發(fā)送方A依次發(fā)出了msg1、msg2、msg3三條消息給接收方B,這三條消息該怎么保證顯示時序的一致性(發(fā)送與顯示的順序一致)?

    我們知道,發(fā)送方A依次發(fā)出的msg1、msg2、msg3三條消息,到底服務端后,再由服務端中轉發(fā)出時,這個順序由于多線程的網絡的問題,是有可能亂序的。

    那么結果就可能是這樣: 

    如上圖所示,會出現(xiàn)與發(fā)出時的消息時序不一致問題(收到的消息順序是:msg3、msg1、msg2)。

    不過,實際上一對一聊天的兩個人,并不需要全局消息時序的一致(因為聊天只在兩人的同一會話在發(fā)生),只需要對于同一個發(fā)送方A,發(fā)給B的消息時序一致就行了。

    常見優(yōu)化方案,在A往B發(fā)出的消息中,加上發(fā)送方A本地的一個絕對時序(比如本機時間戳),來表示接收方B的展現(xiàn)時序。

    那么當接收方B收到消息后,即使極端情況下消息可能存在亂序到達,但因為這個亂序的時間差對于普通用戶來說體感是很短的,在UI展現(xiàn)層按照消息中自帶的絕對時序排個序后再顯示,用戶其實是沒有太多感知的。

    6.2 多對多群聊的消息一致性保證思路

    假設N個群友在一個IM群里聊天,應該怎樣保證所有群員收到消息的顯示時序一致性呢?

    首先:不能像一對聊天那樣利用發(fā)送方的絕對時序來保證消息順序,因為群聊發(fā)送方不單點,時間也不一致。

    或許:我們可以利用服務器的單點做序列化。

    如上圖所示,此時IM群聊的發(fā)送流程為:

    • 1)sender1發(fā)出msg1,sender2發(fā)出msg2;
    • 2)msg1和msg2經過接入集群,服務集群;
    • 3)service層到底層拿一個唯一seq,來確定接收方展示時序;
    • 4)service拿到msg2的seq是20,msg1的seq是30;
    • 5)通過投遞服務講消息給多個群友,群友即使接收到msg1和msg2的時間不同,但可以統(tǒng)一按照seq來展現(xiàn)。

    這個方法:

    • 1)優(yōu)點是:能實現(xiàn)所有群友的消息展示時序相同;
    • 2)缺點是:這個生成全局遞增序列號的服務很容易成為系統(tǒng)瓶頸。

    還有沒有進一步的優(yōu)化方法呢?

    從技術角度看:群消息其實也不用保證全局消息序列有序,而只要保證一個群內的消息有序即可,這樣的話,“消息id序列化”就成了一個很好的思路。

    上圖這個方案中,service層不再需要去一個統(tǒng)一的后端拿全局seq(序列號),而是在service連接池層面做細小的改造,保證一個群的消息落在同一個service上,這個service就可以用本地seq來序列化同一個群的所有消息,保證所有群友看到消息的時序是相同的。

    關于IM的系統(tǒng)架構下使用怎么樣實現(xiàn)消息序列化,或者說全局消息ID的生成方案,這又是另一個很熱門的技術話題。

    有興趣,可以深入閱讀下面這個系列:

    IM消息ID技術專題(一):微信的海量IM聊天消息序列號生成實踐(算法原理篇)

    IM消息ID技術專題(二):微信的海量IM聊天消息序列號生成實踐(容災方案篇)

    IM消息ID技術專題(三):解密融云IM產品的聊天消息ID生成策略

    IM消息ID技術專題(四):深度解密美團的分布式ID生成算法

    IM消息ID技術專題(五):開源分布式ID生成器UidGenerator的技術實現(xiàn)

    IM消息ID技術專題(六):深度解密滴滴的高性能ID生成器(Tinyid)

    這個系列中,尤其微信的趨勢遞增ID生成思路(注意:趨勢遞增不是嚴格遞增,趨勢遞增意味著中問有ID被跳過也沒事),對于分布式IM的消息ID來說是非常切實可行的。

    是的,對于IM系統(tǒng)來說,絕對意義上的時序很難保證,但通過服務端生成的單調遞增消息ID的方式,利用遞增ID來保證時序性,也是一個很可性的方案。

    7、小結一下

    IM系統(tǒng)架構下,消息的絕對時序是很困難的,原因多種多樣,比如:沒有全局時鐘、多發(fā)送方、多接收方、多線程、網絡傳輸不確定性等。

    一對一單聊時,其實只需要保證發(fā)出的時序與接收的時序一致,就基本能讓用戶感覺不到亂序了。

    多對多的群聊情況下,保證同一群內的所有接收方消息時序一致,也就能讓用戶感覺不到亂序了,方法有兩種,一種單點絕對時序,另一種實現(xiàn)消息id的序列化(也就是實現(xiàn)一種全局遞增消息ID)。

    8、參考資料

    [1] 如何保證IM實時消息的“時序性”與“一致性”?,作者:沈劍

    [2] 一個低成本確保IM消息時序的方法探討,作者:封宇

    附錄:更多IM開發(fā)熱門技術點

    移動端IM開發(fā)者必讀(一):通俗易懂,理解移動網絡的“弱”和“慢”

    移動端IM開發(fā)者必讀(二):史上最全移動弱網絡優(yōu)化方法總結

    現(xiàn)代移動端網絡短連接的優(yōu)化手段總結:請求速度、弱網適應、安全保障

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

    移動端IM開發(fā)需要面對的技術問題

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

    請問有人知道語音留言聊天的主流實現(xiàn)方式嗎?

    如何保證IM實時消息的“時序性”與“一致性”?

    一個低成本確保IM消息時序的方法探討

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

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

    談談移動端 IM 開發(fā)中登錄請求的優(yōu)化

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

    淺談移動端IM的多點登錄和消息漫游原理

    完全自已開發(fā)的IM該如何設計“失敗重試”機制?

    微信對網絡影響的技術試驗及分析(論文全文)

    IM開發(fā)基礎知識補課(五):通俗易懂,正確理解并用好MQ消息隊列

    微信技術分享:微信的海量IM聊天消息序列號生成實踐(算法原理篇)

    IM開發(fā)基礎知識補課(六):數(shù)據庫用NoSQL還是SQL?讀這篇就夠了!

    IM里“附近的人”功能實現(xiàn)原理是什么?如何高效率地實現(xiàn)它?

    IM的掃碼登錄功能如何實現(xiàn)?一文搞懂主流應用的掃碼登錄技術原理

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

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

    ▲ 本文在公眾號上的鏈接是:點此進入,原文鏈接是:http://www.52im.net/thread-3189-1-1.html



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


    只有注冊用戶登錄后才能發(fā)表評論。


    網站導航:
     
    Jack Jiang的 Mail: jb2011@163.com, 聯(lián)系QQ: 413980957, 微信: hellojackjiang
    主站蜘蛛池模板: 无码毛片一区二区三区视频免费播放 | 亚洲高清中文字幕免费| 亚洲av永久无码精品网址| 久久精品亚洲福利| 亚洲色成人网一二三区| 久久久久亚洲精品无码网址色欲 | 一个人看www免费高清字幕| 91嫩草免费国产永久入口| 巨波霸乳在线永久免费视频| 国产一区二区免费在线| 亚洲午夜久久久精品影院| 国产亚洲精品美女| 亚洲成人免费网站| 国产亚洲精久久久久久无码77777| 亚洲视频在线一区二区三区| 一级成人a做片免费| 成年男女男精品免费视频网站 | 亚洲人成在线观看| 免费国产在线精品一区| 台湾一级毛片永久免费| 亚洲精品美女久久久久99| 亚洲人成电影福利在线播放| 免费夜色污私人影院网站电影| 1000部拍拍拍18勿入免费视频软件 | 久久午夜伦鲁片免费无码| 亚洲A∨午夜成人片精品网站| 亚洲成AV人片久久| 中文精品人人永久免费| 国产午夜免费秋霞影院| 色在线亚洲视频www| 日本免费一区二区三区| 国产亚洲自拍一区| 国产午夜亚洲精品不卡电影| 在线a级毛片免费视频| 亚洲人成网站在线播放影院在线 | 成年女人永久免费观看片| 亚洲网红精品大秀在线观看 | 女同免费毛片在线播放| 亚洲国产精品自产在线播放 | 久久无码av亚洲精品色午夜 | 蜜芽亚洲av无码一区二区三区 |