Jack Jiang

          我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
          posts - 499, comments - 13, trackbacks - 0, articles - 1

          本文由云信IM技術團隊分享,原題“千萬級在線直播彈幕方案”,本文有修訂和改動。

          1、引言

          疫情期間,線上演唱會是一種很常見的直播娛樂形式,由于線下社交距離的限制,線上形式演唱會比以往更火爆,而對技術的要求也更高。

          本文基于網易云信針對TFBOYS某場線上演唱會的技術支持,為你分享千萬級在線用戶量的直播系統中實時彈幕功能的技術實踐,希望能帶給你啟發。

           

          技術交流:

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

          2、系列文章

          本文是系列文章中的第 9 篇:

          3、彈幕整體技術方案

          本次的彈幕方案以IM聊天室技術為基礎,提供了登錄直播間、發送彈幕、禮物消息等能力。同時按照千萬級在線廣播的目標,為期設計了基于CDN的彈幕廣播服務。

          直播間收發實時消息(也就是彈幕、禮物)的主要流程如下:

          • 1)獲取直播間接入地址;
          • 2)登錄直播間;
          • 3)收發消息(彈幕、禮物)。

          下面將圍繞以上流程的三個階段,在技術上分別闡述如何實現千萬級在線直播實時彈幕的能力。

          4、彈幕技術方案之獲取直播間接入地址

          為了提供穩定高可用的實時彈幕服務,需要通過GSLB(Global Server Load Balancing)服務給用戶分配最佳的接入地址。

          GSLB服務需要從以下幾個維度綜合考慮:

          • 1)用戶網絡類型;
          • 2)機房網絡容量;
          • 3)服務器負載;
          • 4)成本。

          1)用戶網絡類型和機房網絡容量:

          為了用戶能夠快速、穩定的登錄直播間收發消息,一般要根據用戶所在地理位置以及網絡運營商類型綜合考慮給用戶分類接入服務器。

          機房一般提供BGP網絡、三線網絡兩種接入方案,分配服務根據用戶IP地址分析用戶的地域、運營商類型并分配最佳接入地址。

          一般優先按運營商類型分配三線地址(例如電信用戶分配電信接入地址),如果是小運營商或無法識別的IP地址則分配BGP地址,兩種接入方式用戶都可以獲得穩定的網絡環境。

          2)服務器負載:

          單臺服務器能夠承載的TCP長鏈接有限,尤其是在高并發進入直播間的情況下,握手協議需要完成鏈路加密工作,對系統的CPU資源消耗比較大,因此需要實現一套良好的均衡分配策略。

          3)一套基于服務器負載均衡的分配策略:

          長鏈接接入服務器周期性上報當前服務器負載到負載均衡服務集群,負載信息存儲在共享緩存中,接入分配服務根據負載信息動態分配接入地址。

          一般情況下用戶請求直播間地址,地址分配服務會查詢負載均衡服務(或者直接查詢負載緩存),然后根據獲取到的信息分配當前負載最低的服務器。

          在千萬級別的在線直播活動場景下,開播時大量用戶并發進入直播間,分配服務可達50萬到100萬TPS,這么高的TPS下如果還用“一般分配”方案,負載均衡(緩存)服務的TPS和集群之間的機房網絡帶寬非常高,單臺服務器亦可能因為負載信息滯后導致超負荷分配。

          為解決機房內帶寬和超負載分配的問題,我們對分配方案進行了優化:

          • 1)長鏈接服務器上報負載的周期從1秒調整到5毫秒,負載均衡服務器可以更實時的同步負載信息;
          • 2)“地址分配”服務不再按請求查詢負載信息,而是開啟單獨的同步線程周期性(同樣是5毫秒)同步負載數據,從而有效降低負責信息同步的TPS和網絡開銷;
          • 3)“地址分配”服務不在按最低負載分配,而是將服務接入地址按負載排序,單個接入地址分配一定次數后按順序分配下一個接入地址(避免低負載服務器瞬間被打爆)。

          在實際方案落地中,需要結合負載、用戶網絡類型、機房線路容量等因素綜合分配。

          5、彈幕技術方案之登錄直播間

          登錄直播間主要有兩項任務:

          • 1)握手;
          • 2)身份認證。

          1)握手:

          SDK建立TCP長鏈接后,首先向服務器發送握手協議,主要提供SDK版本、協議版本、支持的加密算法等信息,服務器根據SDK提供的信息選擇合適的協議版本以及加密算法,建立安全的通信鏈路。

          我們支持的非對稱算法包括:RSA、SM2等算法。支持的對稱加密算法包括:AES,SM4等(SM2、SM4為國密算法)。

          非對稱加密算法對CPU資源消耗非常高,為了提高性能一般可以考慮選擇合適的密鑰長度,另外針對Java平臺建議考慮使用JNI技術提高非對稱加密計算性能。

          2)身份認證:

          引言中提到的該次直播活動是在線付費直播,因此身份認證包含了賬號認證和業務認證兩部分,即用戶必須使用正確的賬號密碼登錄App,且必須付費購買直播門票才有權限觀看直播。

          為優化系統性能,實時彈幕服務將“地址分配和鑒權”服務進行了特殊優化:

          鑒權中心提供用戶進入直播間彈幕服務的身份鑒權策略配置。在該次直播活動中采用了動態Token的鑒權機制,即根據用戶賬號、登錄時間、分配的接入地址以及鑒權中心按時間區間生成的“隨機數以及對應的Token算法”動態計算鑒權Token。

          用戶打開直播App,首先完成賬號鑒權。在進入直播間時通過業務中心完成直播付費身份認證和彈幕服務地址分配(同步獲取到彈幕服務的動態鑒權token),最后根據接入地址登錄彈幕服務,彈幕服務依據鑒權中心的策略校驗Token正確性。

          動態Token鑒權采用進程本地計算的方式。可以在不訪問用戶服務的情況下完成身份鑒權,在提高登錄認證的性能同時有效的降低了業務成本。

          6、彈幕技術方案之收發消息(彈幕、禮物)

          實時收發消息是直播間的核心業務,主要分為彈幕和禮物兩類:

          • 1)禮物因涉及付費等因素一般通過客戶方業務服務器發送;
          • 2)彈幕消息則可以通過聊天室長鏈接發送。

          在千萬級直播間場景下,因消息量太高,因此需要從消息量、消息體大小、消息比例等多個方面優化,因此我們設計了一套基于優先級隊列的彈幕服務。

          首先:為了節約消息產生的帶寬,在大型直播項目開始階段,就需要對消息格式進行優化,充分精簡消息體大小。例如將禮物消息展示相關的資源文件提前預加載到直播App中,禮物消息轉化為業務編號,可極大的減少消息大小;

          其次:針對上行消息設計流控機制。為了能全局控制上行消息體量,設計了逐級流控方案。上層級根據下層級能夠支撐處理能力設計相對較粗粒度的本地流控機制。在彈幕反垃圾業務階段,因需要全局控制消息量,因此采用分布式全局流控方案;彈幕廣播階段則根據業務廣播需求再一次進行消息流控。

          上行消息通過反垃圾監測后被投遞到彈幕服務處理。基于優先級隊列的彈幕服務首先按業務劃分不同的消息隊列,例如:系統廣播、高優先級禮物、低優先級、彈幕,然后按隊列分配消息比例,最后根據單位時間(1秒)內用戶需要接收到的消息量計算各個隊列應該投遞的消息數量。在實際投遞消息的過程中,若前一個隊列消息量不足,可將剩余的消息數量疊加到下一個隊列,以確保每一個周期都發送足夠的消息給用戶。

          彈幕可通過長連接或CDN廣播給其他用戶。為了給用戶提供極致的彈幕體驗,充分發揮邊緣加速的優勢,在千萬級在線直播場景下優先選擇CDN方案(如下圖所示)。

          基于CDN廣播彈幕有兩種方案:

          1)基于推流的方案:類似于直播視頻推流技術,即將消息偽裝成視頻流的形式推送到CDN,直播App以訂閱數據流的方式同步彈幕信息;

          2)靜態文件加速方案:即彈幕服務將不同隊列中的消息組裝成一個靜態文件,直播App周期性的到CDN服務器下載彈幕靜態文件。

          相對來說:

          • 1)靜態文件加速方案實現更簡單但實時性不高(取決于彈幕同步的周期時長);
          • 2)推流的方案消息實時性更高,但實現相對復雜,且需要考慮到不同終端的兼容性。

          實際項目中可根據場景和終端類型靈活選擇不同的方案。

          為了保障服務的可靠性,可考慮融合CDN的方案,即同時將消息推送到多家CDN廠商,并結合CDN廠商的容量比例以及網絡延遲情況綜合調度(例如基于權重的輪巡調度策略)。

          7、彈幕穩定性設計之單元化部署

          ChatLink和ChatServer采用單元化部署的方案,有以下優點:

          • 1)單元內依賴的核心服務單元之間相互獨立,水平擴展能力好,且單元內服務故障不影響其他單元,可以有效避免整個服務不可用的問題;
          • 2)跨機房部署,避免單個機房容量不足,或單機房不可用問題;
          • 3)彈幕方案采用了單元無狀態的設計理念,因此不需要考慮單元之間同步數據的問題。

          單個直播間的“接入服務”和“彈幕服務”因需要全局控制未采用單元化部署方案,但是在實施階段采用了跨機房部署的方案(包括依賴的存儲資源、服務),可以避免單個機房故障導致服務不可用的問題。

          8、彈幕穩定性設計之單點服務高可用

          針對“接入服務”和“彈幕服務”,除了采用跨機房部署外,在服務設計上核心依賴的存儲資源、服務,采用主備模式。

          例如:心跳負載依賴的緩存服務,單個緩存實例本身高可用,但考慮到極端情況(例如緩存集群內超過一半的服務器宕機導致服務不可用),因此采用主備緩存集群方案,當主集群不可用后,業務主動切換到備用集群,可保障業務在5秒內恢復正常。

          9、幕穩定性設計之系統監控與數據大盤

          為了實時了解系統運行狀態,在彈幕方案中實現了秒級數據大盤方案。

          監控大盤圍繞用戶和消息主要展示以下信息:

          • 1)用戶地域分布變化;
          • 2)上行消息量;
          • 3)廣播消息量;
          • 4)機房出口帶寬;
          • 5)CDN帶寬;
          • 6)消息流控比例;
          • 7)端側CDN彈幕同步指標(成功比例、延遲狀況)。

          為了達成秒級監控的目標,數據收集采用了“業務預聚合+數據中心合并”的實時計算方案。即業務服務直接在本地進程內聚合計算指標上報到數據中心,數據中心僅需要按時間窗口合并監控指標數據即可輸出到監控大盤。

          10、彈幕穩定性設計之故障與應急預案演練

          為確保活動順利完成,彈幕方案還進行了多次故障與應急預案演練措施。

          具體包含兩個方面。

          1)預設故障演練:即針對高可用設計方案的故障演練,按預設有計劃的制造故障,主要驗證高可用方案是否生效。

          2)隨機故障演練:無計劃的隨機制造故障,主要用于檢查應急預案、異常監控報警、數據大盤等應急監測機制是否生效。

          11、相關資料

          [1] 海量實時消息的視頻直播系統架構演進之路(視頻+PPT)

          [2] 百萬在線的美拍直播彈幕系統的實時推送技術實踐之路

          [3] 阿里電商IM消息平臺,在群聊、直播場景下的技術實踐

          [4] 微信直播聊天室單房間1500萬在線的消息架構演進之路

          [5] 百度直播的海量用戶實時消息系統架構演進實踐

          [6] 百萬人在線的直播間實時聊天消息分發技術實踐

          [7] 直播間海量聊天消息的架構設計難點實踐

          [8] vivo直播系統中IM消息模塊的架構實踐

          [9] 萬人群聊消息投遞方案的思考和實踐

          [10] IM中的萬人群聊技術方案實踐總結

          (本文已同步發布于:http://www.52im.net/thread-4299-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
          主站蜘蛛池模板: 淅川县| 沈阳市| 龙井市| 兰州市| 安达市| 北票市| 庄浪县| 邵阳市| 普陀区| 交口县| 临泽县| 观塘区| 沐川县| 江达县| 云林县| 吉安市| 威海市| 潮安县| 南丹县| 尼勒克县| 隆尧县| 凤庆县| 蓬安县| 郯城县| 休宁县| 黑河市| 河池市| 巴林左旗| 正定县| 商南县| 仪征市| 若羌县| 泾阳县| 崇文区| 小金县| 加查县| 景洪市| 青铜峡市| 永新县| 龙川县| 梓潼县|