B 站千萬級長連接實時消息系統的架構設計與實踐

一、引言

在當今數字娛樂時代,彈幕已經成爲直播平臺上不可或缺的互動元素之一。

用戶通過發送彈幕、送禮等,可以實時在直播畫面上展現自己的想法、評論和互動內容,從而豐富了用戶觀看體驗。在這個過程中,實時向終端推送互動信息,就需要用到長連接。

長連接,顧名思義,是應用存活期間和服務端一直保持的網絡數據通道,能夠支持全雙工上下行數據傳輸。其和請求響應模式的短連接服務最大的差異,在於它可以提供服務端主動給用戶實時推送數據的能力。

本文將介紹 B 站基於 golang 實現的千萬級長連接實時消息系統的架構設計與實踐,包括長連接服務的框架設計,以及針對穩定性與高吞吐做的相關優化。

二、本文目錄

_1)_引言

_2)_關聯文章

_3)_架構設計

_4)_高吞吐技術設計

_5)_服務保障技術設計

_6)_進出” 房 “消息的送達保證設計

_7)_未來規劃

_8)_參考資料

三、關聯文章

四、架構設計

4.1 概述

長連接服務是多業務方共同使用一條長連接。

因爲在設計時,需要考慮到不同業務方、不同業務場景對長連接服務的訴求,同時也要考慮長連接服務的邊界,避免介入業務邏輯,影響後續長連接服務的迭代和發展。

長連接服務主要分爲三個方面:

4.2 整體架構

長連接服務整體構架如上圖所示,整體服務包含以下幾個部分。

_1)控制層:_建連的前置調用,主要做接入合法性校驗、身份校驗和路由管控。

主要職責:

_2)接入層:_長連接核心服務,主要做卸載證書、協議對接和長連接維護。

主要職責:

_3)邏輯層:_簡化接入層,主要做長連的業務功能。

主要職責:

_4)消息分發層:_消息推送到接入層。

主要職責:

_5)服務層:_業務服務對接層,提供下行消息推送入口。

主要職責:

4.3 核心流程

長連接主要是 3 個核心流程:

4.4 功能列表

結合 B 站業務場景,下行數據推送,提供如下通用功能:

五、高吞吐技術設計

隨着業務發展壯大,在線用戶越來越多,長連繫統的壓力越來越大,尤其是熱門賽事直播,比如 s 賽期間,全平臺在線人數快達到千萬,消息吞吐量有上億,長連繫統消息分發平均延遲耗時在 1s 左右,消息到達率達到 99%,下面具體分析下長連做了哪些措施。

5.1 網絡協議

選擇合適的網絡協議對於長連接系統的性能至關重要:

接入層拆分成協議模塊和連接模塊:

針對以上第 _1)_點,協議模塊同時給連接模塊提供統一的數據接口,包括連接建立、數據讀取、寫入等。後續增加新協議,只要在協議模塊做適配,不影響其他模塊的長連業務邏輯。

優勢在於:

5.2 負載均衡

採用負載均衡技術可以將請求分發到不同的服務器節點上處理,避免了單一節點的負載過高,提高了系統的擴展性和穩定性。

長連增加控制層,做負載均衡。控制層提供 http 短連接口,基於客戶端和各邊緣節點實際情況,根據就近原則,動態選擇合適的接入節點。

接入層支持水平擴展,控制層可以實時增加、減少分配節點。在 S 賽期間,在線人數快到達千萬時,平衡調度各接入節點,保障了各節點的 CPU 和內存都在穩定的範圍內。

5.3 消息隊列

消息推送鏈路是:業務發送推送,經過服務層推到邊緣節點,然後下發給客戶端。

服務層實時分發到各邊緣節點,如果是房間類型消息,需要推到多個邊緣節點,服務層同時還要處理業務邏輯,很影響消息的吞吐量。

所以增加消息隊列和消息分發層,消息分發層維護各邊緣節點信息和推送消息,提高了系統的併發處理能力和穩定性,避免了因消息推送阻塞而導致的性能問題。

5.4 消息聚合

當有熱門賽事時,同時在線可能達到千萬級別,一條彈幕消息就要擴散到千萬個終端,假如在線的每個人每秒發一條,需要發送消息量就是 1kw*1kw,消息量非常大,此時消息分發層和接入層,壓力都會很大。

分析發現:這些消息都是同一個房間的,屬於熱點房間,比如 s 賽房間,觀衆數量是無法減少的,那隻能在消息數上做文章。業務消息推送不能減少,又要減少擴散的消息數,就想到了消息聚合。

針對房間消息,按照一定的規則進行消息聚合,批量推送:

消息聚合上線後,消息分發層對接入層調用 QPS 下降 60% 左右,極大的降低了接入層和消息分發層的壓力。

5.5 壓縮算法

消息聚合後,降低了消息的數量,但是增加了消息體的大小,影響了寫入 IO,需要減少消息體大小,就想到了消息壓縮。

壓縮算法,選了市面上比較常用的兩個:zlib 和 brotli,進行比較。

抓取了線上業務推送的數據,選擇最高等級的壓縮等級,進過壓縮驗證:

由此可見,brotli 相比 zlib 有很大的優勢,最後選擇了 brotli 壓縮算法。

選擇在消息分發層進行消息壓縮,避免在各接入節點多次重複壓縮,浪費性能。上線後提升吞吐量的同時,也降低的寬帶使用成本。

六、服務保障技術設計

現在有些業務是強依賴長連推送消息,消息丟失,輕則影響用戶體驗,重則阻塞業務後續流程,進而影響業務流水。針對長連服務消息保障,做了如下工作。

6.1 多活部署

多活部署,通過在不同地理位置部署相同的系統架構和服務,實現了系統在單一地域故障時的快速故障轉移,從而提高了系統的穩定性和可用性。

長連服務部署,主要做了以下幾點:

目前線上運行過程中,偶爾會遇到單節點或機房的網絡抖動,通過控制層,對有問題的節點,進行秒級摘流,大大減少了對業務的影響。

6.2 高低消息通道

多業務消息接入長連接,但不同消息之間的重要性是不一樣的,比如彈幕消息和邀請 pk 消息,丟失幾條彈幕對用戶體驗不會影響很大,但如果邀請 pk 消息丟失,則會導致 pk 業務無法進行後續的流程。

針對不同等級的消息,採用了高低優消息通道。重要消息走高優通道,普通消息走低優通道。這樣重要和普通消息進行了物理隔離,消息分發優先保證重要消息。

針對高優通道,做了雙投遞的保障,在接入層做冪等去重。首先重要消息是針對用戶級別的,量不會很大,所以對接入層的壓力不會增加很大。另外雙投遞的 job 是部署在多機房的,這也就降低單機房網絡抖動造成的影響。

高低優通道上線後,遇到過內網出網抖動,當時內網部屬的 job 節點推送消息異常,而云上高優 job 節點可正常推送,很好的保障了高優消息的到達,進而保障了高優業務不受影響。

6.3 高達功能

高低優通道解決的是 job 到接入層的這一個環節,但消息推送聯路涉及到多個環節,比如服務層到 job、接入層到客戶端。

針對整個鏈路,通過實現必達機制來確保終端的到達率,簡稱高達功能。

功能實現:

最終到達率 = (1-(1-r)^(n+1)),其中:r 爲廣播單次到達率,n 爲最大重試次數。

例如:r = 97%、n=2,那麼最終到達率可以達到 (1-(1-0.97)^(2+1)) = 99.9973%

七、全文鏈接

即時通訊網 (52im.net) 社區鏈接:http://www.52im.net/thread-4647-1-1.html,或點擊下文的 “閱讀原文”!

八、參考文獻

**[**1] 手把手教你寫基於 TCP 的 Socket 長連接

http://www.52im.net/thread-4623-1-1.html

[2] 正確理解 IM 長連接、心跳及重連機制,並動手實現

http://www.52im.net/thread-2799-1-1.html

[3] 萬字長文:手把手教你實現一套高效的 IM 長連接自適應心跳保活機制

http://www.52im.net/thread-3908-1-1.html

[4] 用 JWT 技術解決 IM 系統 Socket 長連接的身份認證痛點

http://www.52im.net/thread-2106-1-1.html

[5] TCP/IP 詳解 - 第 11 章 ·UDP:用戶數據報協議

http://www.52im.net/topic-tcpipvol1.html

[6] TCP/IP 詳解 - 第 17 章 ·TCP:傳輸控制協議

http://www.52im.net/topic-tcpipvol1.html

[7] WebSocket 從入門到精通,半小時就夠!

http://www.52im.net/thread-3134-1-1.html

[8] 快速理解 TCP 協議一篇就夠

http://www.52im.net/thread-1107-1-1.html

[9] 快速理解 TCP 和 UDP 的差異

http://www.52im.net/thread-1160-1-1.html

[10] 一泡尿的時間,快速搞懂 TCP 和 UDP 的區別

http://www.52im.net/thread-3793-1-1.html

[11] 到底什麼是 Socket?一文即懂!

http://www.52im.net/thread-3821-1-1.html

[12] 我們在讀寫 Socket 時,究竟在讀寫什麼?

http://www.52im.net/thread-1732-1-1.html

[13] 假如你來設計 TCP 協議,會怎麼做?

http://www.52im.net/thread-3339-1-1.html

[14]  深入操作系統,一文搞懂 Socket 到底是什麼

http://www.52im.net/thread-4146-1-1.html

[15] 通俗易懂,高性能服務器到底是如何實現的

http://www.52im.net/thread-3315-1-1.html

[16] 12306 搶票帶來的啓示:看我如何用 Go 實現百萬 QPS 的秒殺系統 (含源碼)

http://www.52im.net/thread-2771-1-1.html

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/hwUaLFdeksOMwgibbqYkGA