<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

    本文由作者jhon_11分享,有大量修訂和改動。

    1、引言

    如何設計一款高性能、高并發、高可用的im綜合消息平臺是很多公司發展過程中會碰到且必須要解決的問題。比如一家公司內部的通訊系統、各個互聯網平臺的客服咨詢系統,都是離不開一款好用且維護的方便im綜合消息系統。

    那么,我們應該怎么樣來設計一款三高特性的im系統,并能同時支持各個業務線的接入(比如:內部OA通訊、客服咨詢、消息推送等等功能)有呢?

    下面就由我來介紹一下我所負責的公司IM綜合消息系統所經歷的架構設計歷程,以及架構設計過程中的一些思路和總結,希望能給你帶來啟發。

    學習交流:

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

    2、初版IM架構

    2.1 概述

    im第一版設計的初衷是公司需要一款im消息中間件用于支撐客服咨詢業務。

    但是,考慮到為了方便日后其他業務線也能接入消息溝通平臺,所以一開始就將整個消息中心的能力需求給到中間件團隊進行開發,以便除客服外的各業務線接入綜合消息中心,從而實現多元的消息實時觸達能力。

    2.2 初版架構介紹

    初版架構圖如下圖所示:

    針對上面的架構圖,我們逐個解釋一下各模塊的作用。

    1)存儲端:

    在初版的架構下,存儲端我們使用tidb、redis作為主要存儲:

    • [1] redis用于存儲消息已讀未讀,緩存連接信息等功能;
    • [2] tidb作為開源的分布式數據庫,選擇它是為了方便消息的存儲。

    2)mq消息總線:

    我們使用rocketmq來實現消息總線(PS:即分布式情況下,不同im實例間通過MQ進行消息交互)。

    消息總線是整個im的核心,使用rocketmq能支持十萬級別的tps。基本所有服務都要從消息總線中消費消息進行業務處理。

    3)zookeeper注冊中心:各個服務會注冊到zk中,方便服務之間內部進行調用,同樣也可以暴露服務給外部進行調用。

    4)link服務:

    link服務主要用于接收客戶端的ws(WebSocket協議)、tcp、udp等協議的連接。

    同時調用用戶服務進行認證,并投遞連接成功的消息給位置服務進行消費,存儲連接信息。

    ws(WebSocket協議)過來的消息先到link再投遞到消息總線。

    5)消息分發服務:

    消息分發服務主要用于接收消息總線推過來的消息進行處理,按照im內部消息協議構造好消息體后,又推送到消息總線中(比如會推給會話服務、消息盒子、link服務)。

    6)位置服務:

    存儲link的(WebSocket協議)連接、tcp連接等信息,并使用redis進行緩存(key為userId),方便根據UserId查詢到該用戶所登錄的客戶端連接在哪個link上。

    一個用戶在相同設備只能登錄一個,但可以支持多端登錄。

    7)用戶服務:用于存儲所有用戶,提供認證查詢接口。

    8)消息盒子:存儲所有消息,提供消息查詢、消息已讀未讀、消息未讀數、消息檢索等功能。

    9)會話服務:管理會話、群聊會話、單聊會話等功能。

    2.3 整體時序圖

    整體架構的時序圖如下:

    3、初版IM架構存在的問題及思考

    在上節的架構設計介紹中,我們詳細分享了初版IM系統架構的設計思路以及具體流程。

    那么在初版IM架構設計中還存在什么樣的問題,又該如何優化呢?我們一條條來看看。

    3.1 使用MQ消息總線的問題

    正如上節所分享的那樣,我們初版IM架構中,link服務到消息分發服務的消息使用的MQ消息總線。

    初版架構設計中,link服務將消息下推給消息分發服務進行處理時,使用的是mq消息總線(通俗了說,IM集群內不同IM實例間的通信是依賴于MQ進行的消息傳遞),而mq消息總線必然做對有一定的時延(而且時延受制于MQ本身的系統實現和技術策略)。

    舉個例子:

    當兩個處于不同IM實例的客戶端A和B聊天時,A用戶發送消息到link --> 消息總線 --> 消息分發服務 --> 消息總線 --> link --> B用戶。

    正如上面這個例子,im消息投遞流程太長了,并且這樣也會大大降低系統的吞吐量。

    3.2 消息落庫為寫擴散的問題

    其實現階段我們使用的是跟微信一樣的寫擴散策略(詳見《企業微信的IM架構設計揭秘:消息模型、萬人群、已讀回執、消息撤回等》)。

    那么為啥微信使用寫擴散不是缺陷,而對于我們的IM架構來說確是缺陷呢?

    微信的技術特性:

    • 1)微信號稱沒有存儲用戶的聊天記錄,全是實時推送;
    • 2)微信聊天記錄全部會在我們手機端存儲一份,兩臺手機終端上的聊天記錄并不互通,并且互不可見。

    我們的IM綜合消息中心技術特性:

    • 1)綜合消息中心是會有拉取歷史聊天記錄(服務端拉取)的功能,存儲了全量消息;
    • 2)綜合消息中心的客戶端,需要支持網頁版本。

    綜上所述:

    • 1)寫擴散對微信這樣有移動端的富客戶端版本的即時通訊產品十分友好,每個消息在消息分發的時候給處于這個會話(單聊,群聊)下的所有用戶所在客戶端先推送消息,沒找到連接就針對這個用戶寫一個離線緩存消息,那么下次該用戶登錄進來,可以從緩存中拉取到該消息,并且清掉緩存;
    • 2)寫擴散對于我們這類通用綜合消息平臺并不友好,由于接入方大部分是網頁版的客戶端,所以沒有緩存消息的能力,瀏覽器刷新就沒有了任何消息,所以需要實時去服務端拉取歷史消息。假設我是寫擴散,在一個群聊中有五百個用戶,針對這五百個用戶在這個會話,我需要去寫五百條消息,大大的增加了寫io,并且還不能寫緩存(得寫數據庫)。

    3.3 tidb存在不穩定性和事務并發的問題

    tidb是目前主流的開源分布式數據庫,查詢效率高、無需分庫分表。

    但同樣的,tidb存在一些隱藏的問題:

    • 1)tidb在高并發情況下,并發事務會導致事務失敗,具體原因不知;
    • 2)tidb排錯成本高,公司很少有tidb專業運維,經常遇到不走索引的情況。

    3.4 群聊、單聊冗余在同一個服務的問題

    在我們初版的IM架構設計中,單聊和群聊是冗余在會話服務中的,并且冗余在同一張表的。

    其實單聊、群聊從數據角度來說,還是會有些不同(比如業務屬性)雖然都是會話,我們還是需要將這兩個服務拆分開,細粒度的服務拆分能更好的把控整體的邏輯。

    4、升級版IM架構

    4.1 初始架構問題

    正如前面兩節分享的那樣,漸漸的我們發現初版im架構有很大的不足之處。

    在生產上暴露出了以下問題:

    • 1)tps沒達到預期,吞吐量不能滿足公司業務的發展;
    • 2)使用的存儲中間件難以維護(主要是tidb),試錯成本高,經常在生產暴露問題,并且速度越來越慢;
    • 3)消息寫擴散沒有太大必要,并大大增加了系統io次數(原因見上一節);
    • 4)一些特性無法支持,比如消息圖文檢索,消息已讀未讀。

    4.2 升級版im架構介紹

    本次升級后的im架構如下圖所示:

    如上圖所示,改版后的各模塊情況如下:

    • 1)存儲端:存儲端我們改用了mysql,針對消息服務單獨使用了主從mysql集群(主節點用于寫消息、從節點用于消息檢索)——;
    • 2)mq消息總線:與第一版相比沒有改動;
    • 3)link服務:與第一版相比,改動了link服務到消息分發服務的消息推送方式(由MQ總線方式變更為tcp實時推送);
    • 4)消息分發服務:集成了消息處理能力、路由能力,每臺消息分發服務擁有所有link服務的tcp連接;
    • 5)單聊服務:負責單聊會話的管理能力;
    • 6)群聊服務:負責群聊會話的管理能力;
    • 7)用戶服務:提供用戶認證,登錄\注冊能力。

    5、詳細對比針對初版IM架構的改動

    升級版的IM架構,對比初始初始,具體主要是下面這些改動。

    5.1 改進了不同im實例間的消息分發方式

    針對初版MQ消息總結的問題,升級版架構中,我們將link到消息分發服務改為tcp實時連接,百萬客戶端連接同一臺link機器,消息實時觸達能力tps達到16萬。

    link到消息分發服務的改版是本次設計的亮點之一,完全消除了mq推送的時延性,并且路由簡單,幾乎實時觸達。

    舉個例子:當兩個處于不同IM實例的客戶端A和B聊天時

    • 1)初版架構中是:A用戶發送消息到link --> 消息總線 --> 消息分發服務 --> 消息總線 --> link --> B用戶;
    • 2)升級版架構是:用戶A --> link --> 消息分發 --> link --> 用戶B。

    而且:link服務到消息分發服務集群的消息推送使用輪詢負載均衡的方式,保證公平,不會導致個別機器負載過高。

    5.2 取消了位置服務

    取消了位置服務(這里的位置不是指的IM消息里的地理位置消息哦),消息分發服務集成位置服務的能力。

    消息分發服務本身業務簡單,不需要再單獨劃分位置服務,因為會增加網絡io,并且消息分發服務直連link,而讓它負責路由則更加方便。

    5.3 存儲由tidb改成了mysql

    存儲端由tidb改成了mysql,增強了可維護性,消息服務使用mysql主從讀寫分離方式,提高了消息落庫速度與檢索速度的同時,也減輕數據庫壓力。

    前面有提到過使用tidb這樣維護成本高,排查問題難的分布式數據庫是一件很痛苦的事情。

    而我們使用mysql更加穩定,大家對mysql的學習成本相對較低。針對消息服務使用讀寫分離的方式,能大大提高消息的吞吐量。

    5.4 實現了初版無法實現的特性功能

    升級版架構中,我們實現了初版無法實現的特性功能,比如消息已讀未讀、紅包推送、商品鏈接推送等功能。

    新版綜合消息中心加入了消息已讀未讀、發送紅包、鏈接推送等功能,但這些功能帶有一定的業務特性,畢竟不是所有Im都需要,可通過配置取消這些功能。

    5.5 消息由寫擴散改為讀擴散

    升級版IM架構中,消息存儲由寫擴散改為了讀擴散。

    前面我們有提到寫擴散和讀擴散的利弊,對于網頁端IM我們更適合使用讀擴散,只需要落一條消息,大大提高消息服務的吞吐量.

    5.6 增加了門面服務

    升級版IM架構中,我們增加門面服務 im-logic,用于暴露給第三方業務線接口調用。

    初版架構中,都是im的各個服務各自暴露接口給到外部進行調用, 而升級版架中我們統一使用logic服務暴露給外部調用。

    在logic服務針對調用可以做一些處理,這樣不會影響到整體im的通用,不會增加im底層代碼的復雜度,從而將業務邏輯與底層進行解耦。

    6、優化后的效果對比

    針對升級版和初版IM架構,我們也做了一些對比測試,具體的測試過程就是詳細展開了。

    以下是測試結果:

    7、業務線接入im綜合消息系統的業務劃分思考

    7.1 到底該如何設計高性能通用im綜合消息系統

    關于業務線接入im綜合消息系統的業務劃分,我也做了一些總結和思考,為了更形象和易于理解,我這里以客服系統以及企業微信為例來進行分析。

    假如我開發了一款通用的im綜合消息系統,現在有很多業務方需要接入我們,我們該如何進行業務域的清晰劃分就顯得尤為重要,需要在妥協與不妥協中進行平衡。

    就像當前市面上開源的im消息平臺來說,存在的問題主要是:要么是集成了很多的業務邏輯,要么就只是一款單純的客服系統,再或者就是一款IM好友聊天系統,中間的業務劃分并不明確。當然,這也有好處,拿來就能用,并不需要進行二次業務封裝。

    那么,到底如何將im設計為一款真正的高性能通用im綜合消息系統呢?

    通用的綜合消息消息平臺只需要有通用的底層能力:

    以下案例假設在我已經按照上述架構設計了一版im綜合消息中心。

    7.2 以客服系統為例

    客服系統:

    客服系統不光需要實現自身業務,還需要整合im的消息能力(消費im的消息),來進行場景分析,實現會話變更、信令消息推送等邏輯。

    客服系統內部需要根據im的底層支持能力進行相應的業務封裝以及客服系統的客服用戶池,c端用戶池如何初始化到im的用戶中心這些問題都是需要考慮進去的。

    7.3 內部OA通信為例

    內部OA通信:

     

    員工內部OA通信系統需要集成IM好友功能,需要根據im的用戶中心封裝組織架構,用戶權限等功能。

    同時,內部通信系統需要根據im實現消息已讀未讀,群聊列表,會話列表拉取等功能。

    8、本文小結

    im的綜合消息平臺是一款需要高度結合業務的中間件系統,它直接與業務打交道,跟普通的中間件有根本的區別。

    一款好用的im綜合消息平臺,直接取決于你的通用性,可擴展性以及系統吞吐能力。

    希望這篇文章所分享的內容,能對大家開發im時候的思路有所啟迪。

    9、參考資料

    [1] 從零到卓越:京東客服即時通訊系統的技術架構演進歷程

    [2] 從游擊隊到正規軍(一):馬蜂窩旅游網的IM系統架構演進之路

    [3] 瓜子IM智能客服系統的數據架構設計(整理自現場演講,有配套PPT)

    [4] 阿里釘釘技術分享:企業級IM王者——釘釘在后端架構上的過人之處

    [5] 新手入門一篇就夠:從零開發移動端IM

    [6] 零基礎IM開發入門(一):什么是IM系統?

    [7] 基于實踐:一套百萬消息量小規模IM系統技術要點總結

    [8] 一套億級用戶的IM架構技術干貨(上篇):整體架構、服務拆分等

    [9] 一套億級用戶的IM架構技術干貨(下篇):可靠性、有序性、弱網優化等

    [10] 從新手到專家:如何設計一套億級消息量的分布式IM系統

    [11] 企業微信的IM架構設計揭秘:消息模型、萬人群、已讀回執、消息撤回等

    [12] 阿里IM技術分享(三):閑魚億級IM消息系統的架構演進之路

    [13] 一套高可用、易伸縮、高并發的IM群聊、單聊架構方案設計實踐

    本文已同步發布于:http://www.52im.net/thread-3954-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 找到我)。


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


    網站導航:
     
    Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
    主站蜘蛛池模板: 久久精品成人免费观看97| 狠狠色婷婷狠狠狠亚洲综合| 国产成人精品免费久久久久| 国产精品亚洲色婷婷99久久精品| 久久99亚洲网美利坚合众国| 亚洲色欲色欲www在线丝| 全亚洲最新黄色特级网站 | 亚洲精品中文字幕乱码三区| 无码国模国产在线观看免费 | 77777午夜亚洲| 亚洲无成人网77777| 久久夜色精品国产嚕嚕亚洲av| 亚洲毛片不卡av在线播放一区| 免费无码看av的网站| 免费无码精品黄AV电影| 91九色老熟女免费资源站| 无码国产精品一区二区免费3p| 一级毛片aa高清免费观看| 美女羞羞视频免费网站| 亚洲av无码一区二区三区在线播放| 国产成人精品日本亚洲专一区| 久久久亚洲AV波多野结衣| 久久精品蜜芽亚洲国产AV| 亚洲AV日韩AV永久无码下载| 亚洲成AV人片在线观看无码| 亚洲综合图色40p| 亚洲开心婷婷中文字幕| 亚洲无线码在线一区观看| 亚洲乳大丰满中文字幕| 亚洲精品国产精品乱码视色| 亚洲老妈激情一区二区三区| 国产成A人亚洲精V品无码| 亚洲av日韩av无码| 久久久亚洲欧洲日产国码二区| 亚洲精品美女久久久久| 亚洲婷婷综合色高清在线| 亚洲精品第一国产综合野| 亚洲精品无码av中文字幕| 美女羞羞免费视频网站| 亚欧国产一级在线免费| a成人毛片免费观看|