默認
打賞 發表評論 12
想開發IM:買成品怕坑?租第3方怕貴?找開源自已擼?盡量別走彎路了... 找站長給點建議
移動端IM中大規模群消息的推送如何保證效率、實時性?
閱讀(26698) | 評論(12 收藏4 淘帖1

本文原題為“大規模群消息推送如何保證實時性?”,來自瓜子二手車IM負責人:封宇,本次內容有修訂,感謝原作者(原文鏈接在文末)。


1、編者注


眾所周之,群聊是移動端IM的服務端技術難點所在,難在哪?大量的群聊消息,是一條條推給群內成員還是可以使用什么樣的優化策略?試想一個2000人大群,一條消息的發出,如果瞬間被擴散寫成2000條一對一消息的投遞,對于接收方而言不過是一條消息而已,而服務端是以對相對比單聊消息的2000倍處理壓力后的結果。那么服務端在保證消息投遞的同時,面對這么大的壓力該如何解決好效率問題?解決不好效率問題那實時性就不能保證!

當然,實際在生產環境下,群消息的發送都會想盡辦法進行壓縮,并開展各種改善性能的處理辦法,而不是像上述舉例里的直接擴散寫(即2000人群里,一條消息被簡單地復制為2000條一對一的消息投遞)。具體有哪些優先策略?本文或許可以帶給你一些啟發。

封宇分享的其它IM技術資料:


2、相關資料



3、本文背景


公司IM的第一版紅包功能上線后,收集到不少問題。核心問題是消息延遲,導致群里有些人先看到紅包,有些人晚看到紅包,同時導致消息順序混亂。這是個典型的群聊消息優化問題。

4、問題產生的原因


先大致分析一下問題產生的原因。

1)消息量瞬間大增:
搶紅包時大家都比較活躍,不停在群里發消息,尤其群成員比較多的群(500人),每條消息都會給服務端帶來大量的計算工作。

2)后臺邏輯不夠優化:
比如紅包消息沒有單獨的通道,時效性會收到其他消息影響、沒有采用批處理方式、異步處理有些環節還不到位等等。

5、優化前的系統架構和消息處理流程


先看一下系統架構和消息處理流程(如下圖) :
移動端IM中大規模群消息的推送如何保證效率、實時性?_1.jpg

(本文作者在另一篇文章《一套海量在線用戶的移動端IM架構設計實踐分享(含詳細圖文),對這個架構作了詳細記錄和總結,有興趣的同行可以前往閱讀。)

6、精確定位問題的原因


回顧我們的架構設計(見上節中的大圖),我們嘗試精確定位問題的根本原因,原因分析如下。

1)c2g模塊沒有采取批處理方式:
1條群(500人群)消息到達c2g模塊后,c2g模塊為每個人寫收件箱(這里時間延遲較大,優化點),然后在把這條消息變成500條投遞消息(需要批處理,就給Kafka放入一條消息),通過Kafka送給Deliver節點投遞。

2)Deliver模塊的處理沒有批量合并:
Deliver模塊會到Redis中逐條(500條)檢索接收消息用戶的在線狀態(這個點需要批處理,根據用戶Id分布,一次檢索若干用戶的在線狀態),在線的投遞消息(批處理),離線的發送第三方push(批處理)。

3)離線推送流程不優化:
整體流程上,每條消息是先寫了離線收件箱,再推送。這樣效率也不高,需要對這個流程細化以及異步化。

我們來看看微信在這個邏輯上的一些優化思想:
在微信團隊分享的《微信后臺團隊:微信后臺異步消息隊列的優化升級實踐分享》一文中,提到:
移動端IM中大規模群消息的推送如何保證效率、實時性?_212756nzkamr3lq3o9mkqp.png

上圖是群消息投遞業務的簡化流程示意。隨著微信群消息體量的高速膨脹,其帶來的成本壓力越來越大,業務同學提出了批量并行化的優化方式。簡單來說,就是將每個步驟中產生的 RPC 訪問按實際訪問機器聚合成一系列的批量操作,然后并行化執行。  通常來說,單次的批量并行化并不難寫,一般而言,業務同學可能會選擇裸寫。但如果涉及多次的批量并行化,其中還存在嵌套的話,事情就不那么簡單了。最終代碼將變得異常復雜,業務開發的同學苦不堪言。MQ 能否從框架上解決這類問題?


(具體內容詳見文章《微信后臺團隊:微信后臺異步消息隊列的優化升級實踐分享》)

總結一下就是:
微信在這塊的一個重要優化思想是批處理,做法是單次批量操作(我們本次優化目標)裸寫,多條消息的聚合(MapReduce過程)下沉到了MQ中間件中。

7、我們具體怎么做


7.1群聊紅包邏輯單獨部署


現階段,當消息(尤其是大群消息)量大的時候,Deliver節點會成為瓶頸。紅包對時效性要求很高,架構上采用獨立為紅包部署Deliver節點的方式確保紅包消息走單獨通道進行推送。即使其他消息出現延遲,紅包消息依然能保證即使送達。

優化后的架構簡述為下圖所示:
移動端IM中大規模群消息的推送如何保證效率、實時性?_3.jpg

7.2裸寫批處理邏輯


處理一條群消息,服務端要進行大量的工作,需要查詢所有群成員的路由表、在線狀態,在線人員需要推送及時消息,離線人員需要推送第三方push(比如iOS的apns推送通道)。這些工作逐條執行,性能會非常差,如果遇到大群,系統會不可用。

批處理可以較好解決這個問題。比如用戶狀態及路由表數據,采用hash算法分布在幾臺服務器上。收到群消息后,根據群成員,計算出用戶狀態及路由表數據的分布情況,從緩存服務器中一次檢索出該服務器可能存在的所有群成員狀態及路由信息。這樣可以極大減少RPC調用次數,及計算量。

推送操作也類似,批量向接入層投遞消息即可。

7.3離線消息異步寫收件箱


在處理大群消息推送時,寫離線消息也是一個非常影響性能的地方。現有的邏輯是先為每個人寫一條離線消息,再執行推送。這樣做的初衷是確保消息投遞絕對可靠(參看《一個海量在線用戶即時通訊系統(IM)的完整設計》的離線消息章節)。由于大群人數較多,寫離線消息也有較多時間開銷。

優化思路是現將消息及時推送給用戶,再異步寫離線消息,同時處理好寫離線消息和推送消息的ack時序。

具體步驟如下圖:
移動端IM中大規模群消息的推送如何保證效率、實時性?_4.jpg

對上圖的解讀如下:

  • 1)Deliver節點收到一條群消息,檢索用戶在線狀態及路由信息,用戶在線(離線的邏輯相對簡單,略過);
  • 2)批量推送消息(2、批處理邏輯);
  • 3)異步將消息寫入消息總線,同時寫入第三方push的延遲推送任務;
  • 4)異步寫離線消息(不影響在線用戶收到消息的速度);
  • 5)第(2)步推送消息的ack信息回到服務端;
  • 6)c2g模塊將ack信息放入消息總線。(確保消息時序性,ack需要在寫離線消息之后處理,否則可能出現消息重復);
  • 7)刪除對應的離線消息;
  • 8)第(3)步寫入的延遲推送任務,在規定時間(如10秒)后生效,判斷是否存在此條離線消息(如果ack回來了,離線消息會被刪掉),如果離線消息還存在,發送第三方push。

通過以上3個方面的優化,能夠確保在并發消息量較大時,推送消息依然及時。

(原文鏈接:https://mp.weixin.qq.com/s/2oT8bJaSnfH2Zxg8iLAc_A,內容有修訂)

附錄:更多即時通訊技術資料


[1] 有關IM/推送的通信格式、協議的選擇:
簡述傳輸層協議TCP和UDP的區別
為什么QQ用的是UDP協議而不是TCP協議?
移動端即時通訊協議選擇:UDP還是TCP?
如何選擇即時通訊應用的數據傳輸格式
強列建議將Protobuf作為你的即時通訊應用數據傳輸格式
全方位評測:Protobuf性能到底有沒有比JSON快5倍?
移動端IM開發需要面對的技術問題(含通信協議選擇)
簡述移動端IM開發的那些坑:架構設計、通信協議和客戶端
理論聯系實際:一套典型的IM通信協議設計詳解
58到家實時消息系統的協議設計等技術實踐分享
詳解如何在NodeJS中使用Google的Protobuf
>> 更多同類文章 ……

[2] 有關IM/推送的心跳保活處理:
應用保活終極總結(一):Android6.0以下的雙進程守護保活實踐
應用保活終極總結(二):Android6.0及以上的保活實踐(進程防殺篇)
應用保活終極總結(三):Android6.0及以上的保活實踐(被殺復活篇)
Android進程保活詳解:一篇文章解決你的所有疑問
Android端消息推送總結:實現原理、心跳保活、遇到的問題等
深入的聊聊Android消息推送這件小事
為何基于TCP協議的移動端IM仍然需要心跳保活機制?
微信團隊原創分享:Android版微信后臺保活實戰分享(進程保活篇)
微信團隊原創分享:Android版微信后臺保活實戰分享(網絡保活篇)
移動端IM實踐:實現Android版微信的智能心跳機制
移動端IM實踐:WhatsApp、Line、微信的心跳策略分析
>> 更多同類文章 ……

[3] 有關WEB端即時通訊開發:
新手入門貼:史上最全Web端即時通訊技術原理詳解
Web端即時通訊技術盤點:短輪詢、Comet、Websocket、SSE
SSE技術詳解:一種全新的HTML5服務器推送事件技術
Comet技術詳解:基于HTTP長連接的Web端實時通信技術
新手快速入門:WebSocket簡明教程
WebSocket詳解(一):初步認識WebSocket技術
WebSocket詳解(二):技術原理、代碼演示和應用案例
WebSocket詳解(三):深入WebSocket通信協議細節
socket.io實現消息推送的一點實踐及思路
LinkedIn的Web端即時通訊實踐:實現單機幾十萬條長連接
Web端即時通訊技術的發展與WebSocket、Socket.io的技術實踐
Web端即時通訊安全:跨站點WebSocket劫持漏洞詳解(含示例代碼)
開源框架Pomelo實踐:搭建Web端高性能分布式IM聊天服務器
使用WebSocket和SSE技術實現Web端消息推送
詳解Web端通信方式的演進:從Ajax、JSONP 到 SSE、Websocket
>> 更多同類文章 ……

[4] 有關IM架構設計:
淺談IM系統的架構設計
簡述移動端IM開發的那些坑:架構設計、通信協議和客戶端
一套海量在線用戶的移動端IM架構設計實踐分享(含詳細圖文)
一套原創分布式即時通訊(IM)系統理論架構方案
從零到卓越:京東客服即時通訊系統的技術架構演進歷程
蘑菇街即時通訊/IM服務器開發之架構選擇
騰訊QQ1.4億在線用戶的技術挑戰和架構演進之路PPT
微信后臺基于時間序的海量數據冷熱分級架構設計實踐
微信技術總監談架構:微信之道——大道至簡(演講全文)
如何解讀《微信技術總監談架構:微信之道——大道至簡》
快速裂變:見證微信強大后臺架構從0到1的演進歷程(一)
17年的實踐:騰訊海量產品的技術方法論
>> 更多同類文章 ……

[5] 有關IM安全的文章:
即時通訊安全篇(一):正確地理解和使用Android端加密算法
即時通訊安全篇(二):探討組合加密算法在IM中的應用
即時通訊安全篇(三):常用加解密算法與通訊安全講解
即時通訊安全篇(四):實例分析Android中密鑰硬編碼的風險
即時通訊安全篇(五):對稱加密技術在Android平臺上的應用實踐
即時通訊安全篇(六):非對稱加密技術的原理與應用實踐
傳輸層安全協議SSL/TLS的Java平臺實現簡介和Demo演示
理論聯系實際:一套典型的IM通信協議設計詳解(含安全層設計)
微信新一代通信安全解決方案:基于TLS1.3的MMTLS詳解
來自阿里OpenIM:打造安全可靠即時通訊服務的技術實踐分享
簡述實時音視頻聊天中端到端加密(E2EE)的工作原理
移動端安全通信的利器——端到端加密(E2EE)技術詳解
Web端即時通訊安全:跨站點WebSocket劫持漏洞詳解(含示例代碼)
通俗易懂:一篇掌握即時通訊的消息傳輸安全原理
>> 更多同類文章 ……

[6] IM開發綜合文章:
移動端IM中大規模群消息的推送如何保證效率、實時性?
移動端IM開發需要面對的技術問題
開發IM是自己設計協議用字節流好還是字符流好?
請問有人知道語音留言聊天的主流實現方式嗎?
IM消息送達保證機制實現(一):保證在線實時消息的可靠投遞
IM消息送達保證機制實現(二):保證離線消息的可靠投遞
如何保證IM實時消息的“時序性”與“一致性”?
一個低成本確保IM消息時序的方法探討
IM單聊和群聊中的在線狀態同步應該用“推”還是“拉”?
IM群聊消息如此復雜,如何保證不丟不重?
談談移動端 IM 開發中登錄請求的優化
移動端IM登錄時拉取數據如何作到省流量?
淺談移動端IM的多點登陸和消息漫游原理
完全自已開發的IM該如何設計“失敗重試”機制?
通俗易懂:基于集群的移動端IM接入層負載均衡方案分享
微信對網絡影響的技術試驗及分析(論文全文)
即時通訊系統的原理、技術和應用(技術論文)
開源IM工程“蘑菇街TeamTalk”的現狀:一場有始無終的開源秀
QQ音樂團隊分享:Android中的圖片壓縮技術詳解(上篇)
QQ音樂團隊分享:Android中的圖片壓縮技術詳解(下篇)
騰訊原創分享(一):如何大幅提升移動網絡下手機QQ的圖片傳輸速度和成功率
騰訊原創分享(二):如何大幅壓縮移動網絡下APP的流量消耗(上篇)
騰訊原創分享(二):如何大幅壓縮移動網絡下APP的流量消耗(下篇)
如約而至:微信自用的移動端IM網絡層跨平臺組件庫Mars已正式開源
基于社交網絡的Yelp是如何實現海量用戶圖片的無損壓縮的?
>> 更多同類文章 ……

[7] 更多即時通訊技術好文分類:
http://www.uktmgv.tw/forum.php?mod=collection&op=all

即時通訊網 - 即時通訊開發者社區! 來源: - 即時通訊開發者社區!

上一篇:移動IM聊天中發送視頻,截取視頻第一幀圖片是怎樣一個過程?下一篇:現代IM系統中聊天消息的同步和存儲方案探討

本帖已收錄至以下技術專輯

推薦方案
評論 12
之前做的幾個簡單的demo我總以為是群聊簡單的。原裝最難的就是群聊
簽名: 好久不來了 現在不忙了 好好學習
為什么我的頭像在公司和家里的頭像不是一個呢?這個頭像文件是放到本地了么?
引用:liu1348789134 發表于 2017-11-20 13:42
為什么我的頭像在公司和家里的頭像不是一個呢?這個頭像文件是放到本地了么?

瀏覽器的緩存
簽名: 《主流移動端賬號登錄方式的原理及設計思路》http://www.uktmgv.tw/thread-2863-1-1.html
引用:奶瓶 發表于 2017-11-20 13:07
之前做的幾個簡單的demo我總以為是群聊簡單的。原裝最難的就是群聊

局域網寫的demo可以用廣播解決,所以初學會感覺群聊簡單
簽名: 《主流移動端賬號登錄方式的原理及設計思路》http://www.uktmgv.tw/thread-2863-1-1.html
引用:JackJiang 發表于 2017-11-20 13:47
瀏覽器的緩存

光棍節的紀念章能不能給我
引用:liu1348789134 發表于 2017-11-20 17:02
光棍節的紀念章能不能給我

OK 我送你!你屬像勛章太多,我幫你刪掉了
簽名: 《主流移動端賬號登錄方式的原理及設計思路》http://www.uktmgv.tw/thread-2863-1-1.html
引用:JackJiang 發表于 2017-11-20 17:04
OK 我送你!你屬像勛章太多,我幫你刪掉了

thankyou
直接做才發現難
非常不錯的文章,贊一個
厲害厲害
簽名: 又來看看了
可以可以
很好的問題
打賞樓主 ×
使用微信打賞! 使用支付寶打賞!

返回頂部
曾氏料二肖中特