<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

    1、前言


    IM的群聊消息,究竟存1份(即擴散讀方式)還是存多份(即擴散寫方式)?

    上一篇文章《IM群聊消息的已讀回執功能該怎么實現?》是說,“很容易想到,是存一份”,被網友們罵了,大家爭論的很激烈(見下圖)。

    IM群聊消息究竟是存1份(即擴散讀)還是存多份(即擴散寫)?_WechatIMG109.jpg 

    網友罵的對,任何技術方案,都不是天才般靈感乍現想到的,一定是一個演進迭代,逐步優化的過程。今天就聊一聊,IM群聊消息,為啥只需要存一份。

    不過,從公開的技術資料來看,微信的群聊消息應該使用的是存多份(即擴散寫方式),詳細的方案可以在微信團隊分享的這篇文章里找到答案:《微信后臺團隊:微信后臺異步消息隊列的優化升級實踐分享》。

    學習交流:

    - 即時通訊開發交流3群:185926912[推薦]

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

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


    2、本文作者


    IM群聊消息究竟是存1份(即擴散讀)還是存多份(即擴散寫)?_58同城沈劍.jpg 
    沈劍:58技術委員會主席,58高級架構師,58到家技術總監。C2C技術部負責人,58技術學院優秀講師。

    沈劍的另外幾篇有關IM的文章也值得你去閱讀:


    3、IM開發干貨系列文章


    本文是系列文章中的第15篇,總目錄如下:


    另外,如果您是IM開發初學者,強烈建議首先閱讀《新手入門一篇就夠:從零開發移動端IM》。

    4、更多關于IM群聊的文章


    IM系統中的群聊功能,是個很大話題,下面幾篇在關群聊的文章您也可以讀一讀:

    >> 更多同類文章 ……

    另外,《一套海量在線用戶的移動端IM架構設計實踐分享(含詳細圖文)》一文中也包含了群聊的完整設計,如果您設計IM不知從何下手,可以詳細地參考此文。

    5、最基本的方案:“在線的群友不存儲消息,離線的群友才存儲”


    群信息,用戶信息,群成員關系都是基礎數據:

    group_info(gid, group_info);
    user_info(uid, user_info);
    group_members(gid, uid);


    假設一個群(gid)里有4個成員,其中三個在線(A, uid1, uid2),一個不在線(uid3)。

    A發送了一條消息,很容易想到,對于不同的群友消息存多份,每個群友一個隊列來存儲。但由于在線的用戶會實時的收到消息,所以暫定只為離線的用戶存儲。

    用戶收到的群消息,也是基礎數據:

    user_msgs(uid,msgid,gid,sender_uid,time,content);


    IM群聊消息究竟是存1份(即擴散讀)還是存多份(即擴散寫)?_1.jpg 

    很容易想到,整個群消息的發送流程如上圖1-4:

    • 1)發送消息;
    • 2)查詢狀態;
    • 3)不在線的存儲離線;
    • 4)在線的實時推送。

    “在線的群友不存儲,離線的群友才存儲”會帶來的問題是,如果第四步發生異常,群友會丟失消息

    6、優化的方案:“不管群員是否在線,都要先存儲消息”


    消息的可達性是聊天系統中最重要的要素(沒有之一),故這個方案是不行的,需要優化為“不管是否在線,都要先存儲”。

    IM群聊消息究竟是存1份(即擴散讀)還是存多份(即擴散寫)?_2.jpg 

    發送群消息的流程優化為,如上圖1-4:

    • 1)發送消息;
    • 2)所有人都存一份;
    • 3)查詢狀態;
    • 4)在線的實時推送。

    先將消息落地,能夠保證消息可達性,那何時才能刪除已經落地的群消息呢?我們繼續往下看。

    IM群聊消息究竟是存1份(即擴散讀)還是存多份(即擴散寫)?_3.jpg 

    對于在線的群友:收到群消息后,給個ack確認才能刪除。

    畫外音:邏輯刪除,還是物理刪除,根據業務是否有消息漫游決定。

    IM群聊消息究竟是存1份(即擴散讀)還是存多份(即擴散寫)?_4.jpg 

    對于離線的群友:在下次登陸后,拉取完離線消息再給ack確認才能刪除

    總之:為了保證消息的可達性,不管是在線消息還是離線消息,必須接收方給ack確認,才能刪除消息。

    7、“不管群員是否在線,都冗余一份群消息”帶來的問題


    “不管是否在線,都冗余一份群消息”帶來的問題是:同一條消息存儲了很多次,對磁盤和帶寬造成了很大的浪費。

    很容易想到的優化是:群消息實體存儲一份,用戶只冗余消息ID。

    IM群聊消息究竟是存1份(即擴散讀)還是存多份(即擴散寫)?_5.jpg 

    故基礎數據可以由:

    user_msgs(uid,msgid,gid,sender_uid,time,content);
    優化為:
    group_msgs(msgid,gid,sender_uid,time,content);
    user_msgs(uid, msgid, gid);


    這個優化,對于消息投遞,以及消息刪除的核心流程沒有影響,幾個實踐為:

    • 在線用戶投遞消息實體,ack消息ID;
    • 離線用戶先拉取消息ID,再拉取消息實體,再ack消息ID。

    如此這般,假如在某個群友A期間,群里陸續發送了N條消息,則user_msgs(uid, msgid, gid)里,會有 uidA -> mid1,mid2, mid3, … midN 等N條離線記錄,拉取離線消息時,可以把這N條消息一次性拉取出來,然后再刪除:

    delete from user_msgs  where msgid in($mid1,$mid2…, $midN) and gid=$gid


    8、終級方案:利用群消息的“偏序”特性優雅地實現“只存1份”


    然而,群消息具備“偏序”特性,上面的一次性刪除完全可以優化為:

    delete from user_msgs 
    where msgid >= $mid1 and gid=$gid


    這就意味著,每個用戶只需要記錄“最近一次收到的消息ID”,而不用記錄“所有未收到的消息ID集合”,每當收在線消息ack,以及拉離線消息ack時,只需要更新這個“最近一次收到的消息ID”即可。

    于是乎,基礎數據可以由:
    group_members(gid, uid);
    group_msgs(msgid,gid,sender_uid,time,content);
    user_msgs(uid, msgid, gid);

    優化為:
    group_members(gid, uid, last_ack_msgid);
    group_msgs(msgid,gid,sender_uid,time,content);
    user_msgs(uid, msgid, gid); // 不再需要

    IM群聊消息究竟是存1份(即擴散讀)還是存多份(即擴散寫)?_6.jpg 
    即:群消息只存儲一份,群友無需冗余任何消息實體,或者消息ID了。

    IM群聊消息究竟是存1份(即擴散讀)還是存多份(即擴散寫)?_7.jpg 
    對于在線的群友:收到群消息后,修改這個last_ack_msgid。

    IM群聊消息究竟是存1份(即擴散讀)還是存多份(即擴散寫)?_8.jpg 
    對于離線的群友:拉取群消息后,也修改這個last_ack_msgid。

    畫外音:這里的討論,僅限于接收方收到了哪些消息,和發送方的已讀回執沒有關系。(這里指的是作者的上篇文章《IM群聊消息的已讀回執功能該怎么實現?》)

    9、本文小結


    任何架構方案都不是靈光一現,而是逐步迭代優化產生的:

    • 方案1:群聊消息存多份,只存在線,消息容易丟;
    • 方案2:群聊消息存多份,所有群友都存儲,消息冗余多;
    • 方案3:群聊消息存多份,只存ID,未利用偏序;
    • 終極方案:群聊消息存一份,只存last_ack_msgid。

    架構不(只)是設計出來的,更是演進出來的。
    (本文同步發布于:http://www.52im.net/thread-1616-1-1.html

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


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


    網站導航:
    博客園   IT新聞   Chat2DB   C++博客   博問  
     
    Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
    主站蜘蛛池模板: 最近2018中文字幕免费视频 | 美女被吸屁股免费网站| 亚洲AV伊人久久青青草原| 久久国产精品免费一区| 自怕偷自怕亚洲精品| 四虎在线播放免费永久视频| 在线观看人成视频免费无遮挡| 亚洲精品国产成人| 国产大片51精品免费观看| 中文字幕无码日韩专区免费| 亚洲熟妇无码AV| 亚洲精品无码鲁网中文电影| 成人免费无码大片A毛片抽搐 | 免费的一级黄色片| 西西人体免费视频| 亚洲欧洲精品成人久久曰| 亚洲综合色婷婷七月丁香| 免费无码A片一区二三区| 中国内地毛片免费高清| 亚洲人成www在线播放| 亚洲综合伊人久久大杳蕉| 免费毛片在线视频| 99久久免费看国产精品| 免费国产在线精品一区| 精品日韩99亚洲的在线发布| 亚洲成av人影院| 一级毛片直播亚洲| 亚洲中文无码永久免费| 日韩精品免费在线视频| 特级无码毛片免费视频| 亚洲日韩国产精品乱-久| 亚洲欧洲免费视频| 亚洲一区二区精品视频| 国产精品美女自在线观看免费| 最近的中文字幕大全免费8| 91av免费在线视频| 国产亚洲综合视频| 午夜在线a亚洲v天堂网2019| 亚洲激情电影在线| 亚洲AV日韩AV天堂一区二区三区| 亚洲免费在线观看|