1. 程式人生 > >《即時訊息技術剖析與實戰》學習筆記10——IM系統如何應對高併發

《即時訊息技術剖析與實戰》學習筆記10——IM系統如何應對高併發

一、IM 系統的高併發場景

IM 系統中,高併發多見於直播互動場景。比如直播間,在直播過程中,觀眾會給主播打賞、送禮、傳送彈幕等,尤其是明星直播間,幾十萬、上百萬人的規模一點也不稀奇。近期隨著武漢新型肺炎疫情的蔓延,很多教育機構也提供了“停課不停學”的線上直播教學服務,也是一大直播互動場景。

直播互動場景具有這樣的特點:流量峰值具有“短時間快速聚集”的突發性、流量隨著開播和結束而劇烈波動,因而會帶來很大的高併發壓力。

二、IM 系統的高併發解決方案

1.閘道器全量轉發

我們先看兩張圖:


可以看到兩張圖很像,但也有不同之處。
上面的圖是普通聊天場景的流程圖:
① 使用者通過閘道器機進入直播間;

② 閘道器會儲存、維護所有進入直播間使用者的線上狀態;
③ 使用者 A 傳送一條彈幕訊息,經過一系列處理;
④ 通過閘道器機維護的使用者線上狀態,查詢出同一直播間其他使用者的閘道器機,將訊息投遞到這些閘道器機上;
⑤ 閘道器機將訊息推送給使用者的裝置。
也就是:通過維護一個全域性的“線上狀態”,邏輯層在確定好接收人後,通過這個“線上狀態”查詢接收人所在的閘道器機,將訊息投遞給這臺網關機,最後由閘道器機通過長連線進行投遞。

問題來了!如果是一個 10w 人的直播間,每傳送一條訊息,就要對這個“線上狀態”進行 10w 次的查詢,更何況是多人、高頻的訊息傳送呢?!

下面的圖是基於上面的流程進行優化後的流程圖,更適用於高併發聊天場景:

① 使用者通過閘道器機進入直播間,會在每臺網關機本機維護“線上狀態”;
② 使用者 A 傳送一條彈幕訊息,經過一系列處理,投遞給訊息佇列,而每臺網關機均訂閱了這個全域性的訊息佇列,因而都能收到訊息;
③ ;
④ 閘道器機通過本機維護的使用者線上狀態,將訊息推送給使用者的裝置。
這個優化的核心就是:不再去精準地確認這個直播間的使用者在哪些閘道器機上,而是將這個直播間的訊息全量投遞給閘道器機,再由閘道器機將訊息下推給本機連線的使用者裝置,也就是下推服務不依賴外部狀態服務。

2.微服務拆分

對所有業務進行拆分:核心服務和非核心服務。核心服務如發彈幕、點贊、打賞等;非核心服務如直播回放、第三方系統的同步等。核心服務通過 DB 從庫或者訊息佇列的方式與非核心服務解耦依賴,避免被直接影響。

對核心服務進行梳理:容易出現瓶頸點的服務和基本不會有瓶頸的服務。容易出現瓶頸的長連線入服務獨立部署,並且和使用者傳送訊息的上行操作拆分成各自獨立的通道,這樣能夠使訊息上行通道、和推送下行通道互相隔離。

3.自動擴縮容

直播互動場景的監控指標一般可以分為兩大類:

  • 業務效能指標,比如直播間人數、發訊息和信令的 QPS 與耗時、訊息收發延遲等;
  • 機器效能指標,主要是通用化的機器效能指標,包括頻寬、PPS、系統負載、IOPS 等。


通過收集業務效能指標或者機器效能指標,結合模擬線上直播間資料來進行壓測,找出單機、中央資源、依賴服務的瓶頸臨界點,制定相應的觸發自動擴縮容的指標監控閾值,實現自動化。

4.智慧負載均衡

擴容可能會出現舊機器和新機器對於新增流量負載不均衡的問題:

對於長連線入服務前端的負載均衡層來說,大部分都採用普通的 Round Robin 演算法來排程,並不管後端的長連線入機器是否已經承載了很多連線,這樣會導致後續新的連線請求還是均勻地分配到舊機器和新機器上,導致舊機器過早達到瓶頸,而新機器沒有被充分利用。

這是因為負載均衡層支援自定義的均衡演算法只能在某一臺負載均衡機器上生效,無法真正做到全域性的排程和均衡。最好的辦法是接管使用者連線的入口,在最外層入口來進行全域性排程。

比如,在建立長連線前,客戶端先通過一個入口排程服務來查詢本次連線應該連線的入口 IP,在這個入口排程服務里根據具體後端接入層機器的具體業務和機器的效能指標,來實時計算排程的權重。負載低的機器權重值高,會被入口排程服務作為優先接入 IP 下發;負載高的機器權重值低,後續新的連線接入會相對更少。

小結

上面的一些應對高併發的舉措,不僅僅可以用於直播互動場景,也適用於其他業務場景,而選用什麼策略往往是根據業務需求而定。

比如上面提到的全量閘道器轉發,假如有50臺網關節點,原來每臺網關節點只需要取1條訊息,現在卻需要取50條訊息,其中有49條是無效的。為了避免每條訊息都查詢使用者的線上狀態,所有的訊息都發送給所有的閘道器節點,會造成每臺網關機器的流量成倍數增長和資源的浪費,但這是應對高併發的一個有效方式。如果是點對點場景,使用全域性線上狀態來精確投遞是更好的選擇,如果是群聊和直播的場景推薦使用所有閘道器來訂閱全量訊息的方式,而採用什麼方式根據需要來權衡