1. 程式人生 > 其它 >im即時通訊開發:萬人群聊技術方案實踐

im即時通訊開發:萬人群聊技術方案實踐

在不瞭解IM技術的人眼裡,群聊是再平常不過的功能而已,萬人群聊?應該也不難實現吧?!

確實,從前端功能介面上來看,群聊無非就是個迴圈向群員傳送訊息的一對多聊天訊息分發模式而已,難在何處?

真實的情況是,群聊是IM系統中的高難度技術點之一。難在哪?難在服務端!從某種角度上說,群聊功能的架構設計和技術實現的品質,可以代表這款IM軟體的技術水平。

群聊從後臺的技術實現上說,至少有以下難點:

    1)如何高效地進行大量群員訊息的分發?

    2)如何高效地管理群員的線上狀態?

    3)如何高效地讀取群員的線上狀態?

    4)集群系統中,如何高效地保證群員訊息的準確送達?

    5)群聊訊息該擴散寫還是擴散讀?

    6)如何保證大量群聊訊息分發的情況下不影響單聊訊息體驗?

    7)如何應對大群突發事件下的效能負載?

    .... ....

目前,市面上主流的IM產品中,微信群是500人上限,QQ群是3000人上限(3000人群是按年付費升級,很貴,不是為一般使用者準備的)。一方面,從產品的定義上群成員數量不應過多,另一方面,技術成本也是個不可迴避的因素。萬人群這種超大規模群的技術難度,更是難已想象。

隨著移動網際網路的發展,即時通訊服務被廣泛應用到各個行業,客戶業務快速發展,傳統百人或千人上限的群聊已經無法滿足很多業務發展需求,因此網易雲信IM推出萬人群服務。

萬人群場景需要解決以下問題:

1)訊息需要按1:9999的比例進行轉發投遞,按常規訊息處理流程將產生大量的子任務,對系統吞吐量的要求極高;

2)在微服務系統架構下,如果不採用一些優化方案,服務以及儲存(DB、快取等)之間的QPS和網路流量將非常高;

3)以群為單位的快取(如群成員列表)記憶體儲存開銷較大(假設一個成員200Byte,萬人群約2MB);

4)群成員登入後需要同步群離線訊息,智慧手機上App前後臺切換產生的較多登入同步訊息協議,因此需要優化訊息同步方案。

萬人群訊息的處理流程

1)按群維護線上群成員資訊,主要包含兩部分(可以理解為兩個快取集合):

    a. 群成員線上資訊:即使用者線上狀態變化(上線、下線)時,更新相應群的線上狀態資訊(即動態維護群有哪些成員線上);

    b. 成員IM長連線資訊:即使用者新登入時,更新使用者的Link資訊(即登入所在Link的地址資訊,訊息轉發時根據Link地址路由訊息)。

2)IM Server收到群訊息後,按群ID將訊息路由到“群訊息服務”模組;

3)群訊息模組檢查並預處理訊息內容,然後通過“群成員線上狀態”服務獲取線上成員,完成訊息轉發的基礎工作。為了減少群訊息模組和群線上成員服務之間的網路流量,採用了“本地快取+增量同步”的快取策略,即本地快取記錄最後更新版本號和時間戳,每次同步群線上成員前先檢查快取版本號是否有變更,若有則按最後更新時間增量同步;

4)通過“群成員線上服務”獲取線上群成員的Link連結資訊,按Link分組路由訊息(分組路由的原因:同一Link上的全部群成員只需要路由一條訊息即可)。同樣為了減少網路開銷,成員Link資訊也採用“本地快取+增量同步”的方案;

5)群訊息採用“漫遊+歷史”的儲存方案,漫遊的訊息儲存在分散式快取中,歷史訊息非同步寫入HBase。使用者登入後可以通過漫遊快速的獲取到最新訊息,並可以通過拉取歷史檢視更早的訊息。

萬人群方案本地快取增量同步策略

拋開群線上狀態管理邏輯,群成員線上狀態服務可以簡單理解為分散式集中快取。即時通訊開發

1)資料快取是一個集合,其包含了多個快取資料項,每一個數據項帶有最後更新時間資訊;另外快取還有一個嚴格遞增的版本號;

2)快取資料變更(新增、修改、刪除)後,需要增加版本號;

3)本地執行緒通過快取管理讀取資料時,管理服務先檢查本地版本號和分散式快取中的版本號是否一致,若不一致則按本地最新時間戳增量同步新資料項,並更新本地的版本號和最後更新時間(為了免分散式集中快取中併發寫入導致的增量時間戳不可靠問題,增量更新時可以將本地記錄的最後更新時間戳向前推移,比如減少20ms);

4)為避免本地多執行緒併發讀取相同資料項導致併發更新本地快取的問題,可以按快取資料合併更新請求,即解決併發問題還可以減少網路開銷;

5)快取資料由大量資料項構成,為了避免單個快取資料太大,可以將資料項中的屬性業務場景精簡(冷熱分離),低頻次讀寫的屬性額外快取。

萬人群水平擴容方案

萬人群採用大量本地快取的方案解決訊息處理效能和網路流量的問題,因此本地儲存空間成了方案的瓶頸點。