直播系統(tǒng)聊天技術(四):百度直播的海量用戶實時消息系統(tǒng)架構演進實踐

本文原題“百度直播消息服務架構實踐”,由百度APP消息中臺團隊原創(chuàng)分享于“百度Geek說”公眾號,為了讓文章內容更通俗易懂,本次已做排版優(yōu)化和內容重新劃分,原文鏈接在文末。
1、引言
一套完整的直播系統(tǒng)核心功能有兩個:
1)實時音視頻的推拉流;
2)直播間消息流的收發(fā)(包括聊天消息、彈幕、指令等)。
本文主要分享的是百度直播的消息系統(tǒng)的架構設計實踐和演進過程。
實際上:直播間內用戶的聊天互動,雖然形式上是常見的IM聊天消息流,但直播消息流不僅僅是用戶聊天。
除用戶聊天外:直播間內常見的用戶送禮物、進場、點贊、去購買、主播推薦商品、申請連麥等互動行為的實時提醒,也是通過消息流下發(fā)的。
此外:直播間關閉、直播流切換等特殊場景,也依賴消息流的實時下發(fā)。
所以,直播系統(tǒng)內的消息流可以認為是直播間內主播與用戶間實時互動和直播間實時控制的基礎能力,也是系統(tǒng)支撐。如果說實時音視頻推拉流是直播系統(tǒng)的靈魂,那消息流可以說是直播系統(tǒng)的骨架,它的重要性不言而喻。
那么,如何構建直播的消息系統(tǒng),又有哪些挑戰(zhàn)需要解決,借著本文我們一起來梳理一下。

學習交流:
- 即時通訊/推送技術開發(fā)交流5群:215477170?[推薦]
- 移動端IM開發(fā)入門文章:《新手入門一篇就夠:從零開發(fā)移動端IM》
- 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK
(本文同步發(fā)布于:http://www.52im.net/thread-3515-1-1.html)
2、系列文章
本文是系列文章中的第4篇:
《直播系統(tǒng)聊天技術(一):百萬在線的美拍直播彈幕系統(tǒng)的實時推送技術實踐之路》
《直播系統(tǒng)聊天技術(二):阿里電商IM消息平臺,在群聊、直播場景下的技術實踐》
《直播系統(tǒng)聊天技術(三):微信直播聊天室單房間1500萬在線的消息架構演進之路》
《直播系統(tǒng)聊天技術(四):百度直播的海量用戶實時消息系統(tǒng)架構演進實踐》(* 本文)
3、與普通IM群聊的區(qū)別
直播間內的聊天消息,經常被類比于普通的IM群聊功能。
群聊是大家比較熟悉的即時通訊(IM)場景,直播間內聊天和群聊,二者有相似性,但也有本質的區(qū)別。
對比二者的特點,直播消息與IM群聊主要有以下區(qū)別:
1)參與人數不同:IM群聊的參與人數上千人就是很大的群了。但對于高熱度的大型直播場景,例如國慶、閱兵、春晚等,單直播間累計用戶是百萬甚至千萬量級的集合,同時在線人數可達數百萬人。
2)組織關系不同:IM用戶進群退群,是相對低頻的操作,用戶集合相對固定,用戶進出的變更頻度不會特別高。而用戶進出直播間,是非常頻繁的,高熱度直播的單直播間每秒面臨上萬用戶的進出變更。
3)持續(xù)時間不同:IM群聊建立后,聊天持續(xù)時間可能比較長,幾天到數月都有。而直播間大部分持續(xù)不超過幾個小時。
4、核心技術挑戰(zhàn)
根據上節(jié)中,直播消息和IM通聊的類比分析,針對直播中的消息系統(tǒng),我們可以提煉出兩個核心技術挑戰(zhàn)。
挑戰(zhàn)一:直播間內用戶的維護
1)單直播間每秒上萬用戶的進出變更(實際進入直播間峰值不超過2萬QPS,退出也不超過2萬QPS);
2)單直播間同時數百萬用戶在線;
3)單直播間累計用戶達千萬量級。
支持在線百萬、累積千萬兩個集合,每秒4萬QPS更新,有一定壓力,但有支持高讀寫性能的存儲應該可以解決,例如redis。
挑戰(zhàn)二:百萬在線用戶的消息下發(fā)
面對百萬在線用戶,上下行都有大量的消息,從直播用戶端視角分析:
1)消息的實時性:如果消息服務端做簡單消峰處理,峰值消息的堆積,會造成整體消息延時增大,且延時可能產生很大的累積效應,消息與直播視頻流在時間線上產生很大的偏差,影響用戶觀看直播時互動的實時性;
2)端體驗和性能:端展示各類用戶聊天和系統(tǒng)消息,一般一屏不超過10-20條。如果每秒有超過20條的消息下發(fā),端上展示的消息基本會持續(xù)刷屏。再考慮到有禮物消息的特效等,大量的消息,對端的處理和展示,帶來持續(xù)高負荷。所以,對于一個長時間觀看直播的用戶端來說,如果出現(xiàn)持續(xù)的大量消息,端的消息消費會有顯著的性能壓力,且過多消息會有累積效應。
由于技術挑戰(zhàn)一不難解決,以下內容主要討論技術挑戰(zhàn)二。
5、技術設計目標
綜合考慮上節(jié)的技術挑戰(zhàn)和直播業(yè)務場景,我們對于消息系統(tǒng)的需求目標有比較明顯的指標定義。
技術設計目標定義大致如下:
1)實時性方面:端和端的消息要達到秒級;
2)性能方面:消息服務能支持同一直播間內百萬以上用戶同時在線下發(fā);
3)峰值處理:對于峰值時的過多消息,丟棄是合理適當的處理方式;
4)基于合理的端用戶體驗,單直播間內每秒消息數假設不超過N條。
現(xiàn)在:問題的核心是,如何做到把不超過N條的消息,在S秒內,下發(fā)到直播間內的百萬用戶(假設 N<=20,S<=2)。
6、從普通IM群聊的技術實現(xiàn)上找靈感
6.1 普通IM群聊消息收發(fā)分析
IM群聊數據流及壓力點:?

如上圖所示,首先具體分析一下普通群聊的消息收發(fā)流程:
1)對于群group-1,分配一個群公共消息信箱group-mbox-1;
2)群group-1內的用戶user-1,由手機端APP-1上發(fā)出消息msg-1;
3)服務端接收到消息msg-1,檢查user-1是否有權限,如有權限,將msg-1存儲到群信箱group-mbox-1,生成相應msgID-1;
4)服務端查詢group-1對應的用戶列表groupUserList-1;
5)基于groupUserList-1拆分出所有獨立群用戶:user-1、user-2 ... user-n;
6)對于每一個用戶user-i來說,需要查詢用戶user-i的所在設備device-i-1、device-i-2、device-i-m(因為一個賬號可能登錄多個設備);
7)對于每個設備device-i-j來說,長連接通道都會建立一個獨立的長連接connect-j以服務于該設備;但由于connect-j是由端上APP-1連接到長連接服務的,具有動態(tài)性,所以,查詢device-i-j與connect-j的對應關系時,需要依賴一個路由服務route來完成查詢;
8)在查得connect-j后,可以通過connect-j下發(fā)msg-1的通知groupmsg-notify-1;
9)如果用戶user-i正在使用device-i-j的手機端APP-1,用戶user-i就可以立即從長連接connect-j上收到msg-1的通知groupmsg-notify-1;
10)在接收到groupmsg-notify-1后,手機端APP-1中的消息SDK根據端本地歷史消息記錄的最后一條消息latestMsg對應的消息ID即latestMsgID,來向服務端發(fā)起拉消息請求fetchMsg,拉取group-1中從latestMsgID+1到最新的所有消息;
11)服務端收到拉消息請求fetchMsg后,從group-mbox-1中取出latestMsgID+1到最新的所有消息,返回給端;如果消息過多,可能需要端分頁拉?。?/p>
12)端APP-1拉取到group-1中從latestMsgID+1到最新的所有消息,可以做展示;在用戶在會話中閱讀后,需要設置所有新消息的已讀狀態(tài)或者會話已讀狀態(tài)。
6.2 普通IM群聊主要壓力
如果完全重用普通群聊消息的下發(fā)通知到端拉取的全過程,對于user-1發(fā)的一條消息msg-1,如果需要支持一個實時百萬量級的群消息,大概有以下幾個每秒百萬量級的挑戰(zhàn)。
首先:秒級拆分出用戶列表groupUserList-1,需要秒級讀出百萬的用戶列表數據,對于存儲和服務是第一個百萬級挑戰(zhàn)。
第二:對于拆分出群中的所有獨立用戶user-i,需要秒級查詢出百萬量級的device-i-j,對于存儲和服務是第二個百萬級挑戰(zhàn)。
第三:對于所有device-i-j,通過動態(tài)路由服務route,需要秒級查詢出百萬量級的connect-j,對于存儲和服務是第三個百萬級挑戰(zhàn)。
第四:對于通過長連接connect-j下發(fā)時,需要支持秒級下發(fā)百萬量級的群消息通知groupmsg-notify-1到對應的connect-j上,對于長連接服務是個百萬級的挑戰(zhàn)。
第五:對于收到消息通知的所有端APP-1,需要支持百萬QPS端從服務端拉取消息請求fetchMsg,對于消息信箱服務,這是也是一個百萬量級的挑戰(zhàn);考慮到實際各端latestMsgID可能不同,可能的優(yōu)化方式會更復雜一些,帶來的性能影響會更大。
第六:如果在絕大多數用戶是在線聊天的場景,設置已讀狀態(tài)也會有百萬量級QPS對服務端的壓力。
顯然:完全重用群聊的消息流程,對消息服務和長連接服務帶來的壓力是巨大的。
6.3 普通IM群聊優(yōu)化方案
IM群聊數據流優(yōu)化后的壓力點:

如上圖所示,現(xiàn)在我們來分析以上每個百萬量級的挑戰(zhàn),是否有優(yōu)化的空間:
1)對于①拆分用戶列表和②查詢用戶對應設備,如果存儲上將二者合并集中起來,也就是優(yōu)化直播間內用戶列表的存儲,擴展設備信息,可以減少一次user->device的百萬QPS查詢,可以優(yōu)化;
2)對于④下行通知和⑤端拉取fetchMsg的可靠消息拉取模式,考慮到直播消息允許部分折損丟棄,可以只做單向消息下發(fā),而不做拉取,對于大部分連接保持在線的用戶,也是可以接受的。所以可以優(yōu)化,只保留下行通知(包含消息體),而舍棄端拉?。?/p>
3)對于⑥消息設置已讀,直播場景下可以考慮簡化舍棄。
如上優(yōu)化后,減少了②⑤⑥三個百萬量級壓力請求,但還有①拆分用戶列表③動態(tài)路由查詢④長連接下發(fā),這三個百萬量級步驟需要處理。
對于①拆分用戶列表:支持百萬量級用戶列表查詢,比較常規(guī)的思路是支持基于群groupID的批量查詢,例如一次可以查出100個用戶,1萬QPS查詢就可以支持到百萬;基于群groupID把用戶數據的存儲,分散到多個主從實例和分片上,控制好打散粒度不出現(xiàn)熱點,基本能做到,只是存儲資源可能消耗較多。
對于③動態(tài)路由查詢:表面上看,面臨的問題與①類似,但卻有些不同。因為群的用戶列表,是基于群groupID做key,建立一個表或多個打散的表;而device-i-j的查詢是完全分散的,也是需要批量查詢能力,但是完全分散的設備信息查詢,不能只針對特定key做優(yōu)化,需要動態(tài)路由服務支持整體上達到百萬QPS的查詢性能。
對于④長連接服務下發(fā):由于長連接服務不依賴外部的存儲服務,如果整體要支持百萬量級的下發(fā)能力,若長連接單實例能支持1萬的下發(fā)能力,整體上100個實例就能支持到百萬量級下發(fā)。
基于以上分析:支持百萬量級的消息下發(fā),初見曙光。似乎只要優(yōu)化好用戶列表、動態(tài)路由的存儲/查詢和長連接的容量擴容,但所有的前提是需要消耗大量存儲和機器資源。
考慮到直播業(yè)務的實際情況,現(xiàn)實不容樂觀:
1)一方面,平時沒有熱點直播時,可能單場直播并發(fā)在線用戶數峰值不超過1萬人,甚至不到1000;在業(yè)務初期,整體直播在線用戶峰值可能也不超過10萬。這就意味著,為了支持百萬量級的峰值,資源整體上有幾十倍的冗余;
2)另一方面,如果突然來了一場熱度非常高的直播,可能需要支持的不只是100萬量級消息下發(fā),可能是500萬以上的量級(例如國慶閱兵、春晚等)。這樣的話,每次大型直播得提前預估可能的在線用戶峰值,如果超過當前設計容量,需要對①用戶列表③動態(tài)路由查詢④長連接服務,分別擴容和壓測;或者在可接受的情況下,做服務降級或拒絕服務。
而實際上:在線用戶峰值量級很難估計準確,這樣會造成實際資源利用率很低,擴縮容的操作頻繁,運維成本高。是否選擇這個方案,也是很令人糾結。
6.4 普通群聊多群組方案
也有人提過拆分多個群組的方案。
例如:如果一個群組最多支持1萬用戶,開100個群就可以支持一百萬用戶;再建立一個虛擬群,將這100個群關聯(lián)起來,似乎可行。
但如果仔細分析,會發(fā)現(xiàn)以上提到的幾個問題:“①拆分用戶列表、③動態(tài)路由查詢、④長連接下發(fā)”,高壓力依然存在,還是不可避免。
除此之外,多群組還會引入其他問題:
1)問題一:多群組消息不同步。如果兩個用戶在一起看直播,而所屬群不同,看到的消息會完全不同;
2)問題二:直播場景用戶是動態(tài)進出的,也就是說群組成員非常不穩(wěn)定,在線用戶峰值波動也比較大。如果是根據在線人數增長,動態(tài)新開群組,可能第一個群用戶已經很多了,第二個群剛開始用戶比較少;或者,在峰值期間開了比較多的群,隨著熱度降低用戶離開,用戶變得分散,一些群的用戶可能較稀少,聊天互動較少,這時需要縮容合并群。如何平衡多個群的用戶,達到好的業(yè)務效果,也是比較難做的。
基于以上分析,我們并沒有選擇多群組方案。
7、基于組播mcast方案的消息架構實踐
經過上節(jié)中類比普通IM群聊消息的架構設計,本節(jié)將介紹我們支持實時高并發(fā)百萬量級同時在線用戶的直播消息架構——組播mcast方案的提出及演化。
7.1 跳出原有框架思考
是否要采用上節(jié)基于IM群聊的優(yōu)化方案,還是可以另辟蹊徑?
先暫時拋開群收發(fā)消息流程:對于消息下發(fā)來說,如果一定要說一個步驟是必不可少的,那一定是長連接下發(fā)這步了。沒有通過長連接下發(fā),消息就無法最終到達用戶。
當然有人說輪詢拉取也可以替代長連接下發(fā),來獲取消息,但顯然輪詢拉取的性能壓力和實時性與長連接下發(fā)相比差很多,故不在討論范圍。
如果能簡化為:給長連接服務下發(fā)消息時指定一個類似的groupID,長連接服務能直接拆分到所有群組用戶相關的長連接connect-j,就可以省略掉用戶列表拆分和動態(tài)路由查詢的百萬量級查詢。
這樣的話:消息下發(fā)的壓力將主要由長連接服務來承受,服務端也不需要對多個系統(tǒng)擴容,直播消息的優(yōu)化可能會大為簡化。
根據這個思路:相當于在長連接服務中,對連接connect也建立群組的概念?;谶B接組的設想,我們設計了一套長連接的組播mcast機制。
7.2 長連接組播mcast基本概念
基本概念總結如下:
1)每個長連接組播mcast有全局唯一的標識mcastID;
2)長連接組播mcast支持創(chuàng)建、刪除、修改、查詢等管理操作;
3)長連接組播mcast是若干長連接在線用戶的連接connect的集合;
4)一個用戶user-i在設備device-i-j上,對于特定應用APP-k來說,建立唯一的一個長連接connect-j-k(此處暫時不區(qū)別登錄用戶和非登錄用戶);
5)長連接組播mcast與組內長連接connect-j-k的關系維護,不需要額外的獨立存儲,是維護在每個長連接服務的實例上。
7.3 長連接組播mcast的路由概念
組播mcast-m的路由route-m,是一個長連接服務實例的集合LcsList,記錄了所有加入mcast-m的長連接connect-i所在長連接服務實例lcs-j。
7.4 長連接組播mcast路由的記錄維護
加入組播mcast的邏輯流程:
1)客戶端調用消息sdk加入mcast-m;
2)消息sdk通過長連接,發(fā)出上行請求mcastJoin(mcast-m);
3)業(yè)務層收到來自長連接實例lcs-i上的連接connect-i的mcastJoin請求,校驗mcast-m的合法性;
4)業(yè)務層請求路由層建立基于組播mcast-m的組播路由mcastRoute-m,將長連接實例lcs-i加入組播路由mcastRoute-m中;
5)業(yè)務層請求長連接服務層,請求mcastJoin所在長連接實例lcs-i,將請求所在連接connect-i加入到mcastConnectList-m中。
離開組播mcast,與加入組播mcast基本類似,由客戶端調用消息sdk離開mcast-m,發(fā)出上行請求mcastLeave(mcast-m),長連接服務端更新路由和mcastConnectList-m信息。
7.5 組播mcast消息推送
組播mcast數據流及壓力點:

基于組播mcast的長連接消息推送過程,是一個?1:M * 1:N?的擴散放大過程。
具體過程描述如下:
1)一條消息msg-1推送,目的地是ID為mcast-m組播;
2)后端業(yè)務模塊根據目的mcast-m,做一致性hash選擇出mcast路由分發(fā)模塊實例mcastRouter- i,發(fā)送msg-1到mcastRouter-i;
3)mcast分發(fā)路由模塊實例mcastRouter-i,根據mcast-m的組播路由mcastRoute-m,查找所對應的接入實例路由記錄列表mcastLcsList-m,拆分出mcast-m所有的長連接接入實例lcs-1..lcs-M,分別并發(fā)發(fā)送msg-1到長連接實例上;
4)一個長連接服務實例lcs-j,收到消息msg-1推送后,根據組播mcast-m查找組播連接列表mcastConnectList-m,查出mcast-m內所有的連接connect-m-1..connect-m-N,并發(fā)推送msg-1到消息客戶端sdk-m-1..sdk-m-N;
5)消息客戶端sdk-m-o收到msg-1后,遞交給上層業(yè)務(例如直播sdk)。
7.6 組播mcast機制的性能評估
現(xiàn)在分析一下以上的組播mcast機制的性能壓力:
1)組播mcast的路由維護,主要壓力在于mcastJoin和mcastLeave,而Join的量級峰值請求很難超過2萬qps;訪問壓力比百萬低兩個數量級;
2)組播mcast的消息推送流程,在一級路由mcastRoute拆分到長連接實例時,一般在幾十到百量級,成本很低;
3)組播mcast在長連接單實例內的消息推送,是單進程內的多連接并發(fā)發(fā)送,經優(yōu)化后線上實測,在單實例保持25W長連接的情況下,單實例壓測可達8Wqps的mcast穩(wěn)定下發(fā),保守按5Wqps容量評估;多個長連接實例間,是完全的并發(fā),可以較容易的水平擴容。
綜上可知:對于100Wqps的下發(fā),20個長連接實例就可以完全負荷(20*5W=100W),且有一定裕量。如果500Wqps的下發(fā),也不超過100實例;1000W的下發(fā),如果以8W單實例較大的負荷承載,125實例就可以支持。

看上去,基于以上組播mcast機制,我們建立了一套高效的支持百萬量級QPS的長連接下發(fā)機制,當前長連接服務的容量就可以支持,基本不用擴容。但是否能完全滿足直播業(yè)務場景需求,還需要進一步討論。
7.7 消息峰值問題
對于每秒1條消息,擴散到100W用戶,甚至500W用戶,以上組播mcast機制似乎都能應對。
但直播間內消息的實際情況是:熱門的直播每秒用戶上行聊天消息會有很多,除聊天消息外,直播間還有人數、進場、點贊、分享等定期和不定期發(fā)送的很多種類系統(tǒng)消息。
如果假設每秒峰值有100條各類消息:100W*100=1億,簡單按單實例5Wqps算,需要2000個實例才能支持,雖然比老的群聊系統(tǒng)應該好很多,但系統(tǒng)還是遇到大量資源冗余或應對峰值需要大量擴容的老問題。是否能有更好的解決方式?
這里我們考慮常見的一個優(yōu)化思路,是通過批量聚合的模式來提高系統(tǒng)性能。
如果將這100條消息每秒聚合打包一次來統(tǒng)一下發(fā),QPS還是100W,長連接系統(tǒng)的下發(fā)QPS不變,但每秒下發(fā)消息量級可以達到1億,這個聚合方案實測是可行的。
聚合模式,我們付出的成本是消息時延的上升,1秒的聚合平均時延增加500ms,用戶體驗損失不算大,但系統(tǒng)下發(fā)消息量級可以提升百倍,綜合評估成本收益來看是合理的??紤]到直播的實際場景,大多數場景下秒級的聚合和時延是可以接受的。
7.8 消息帶寬問題
如上節(jié)所分析的,聚合延時下發(fā),長連接單實例QPS問題解決了,隨之而來的是,長連接單實例下發(fā)的帶寬壓力問題。
例如:長連接單實例需要下發(fā)10000長連接時,每秒100消息,消息平均2K字節(jié),實際帶寬為2K*100*10000*8=15625Mbps,這已經超過單物理機的萬兆網卡的帶寬容量。
另一方面:從全局帶寬來看,也高達1.5Tbps,帶寬資源對于機房出口也會帶來壓力,這樣的帶寬成本過高,需要削減帶寬使用或有更好的替代方案。
面對下發(fā)數據量帶寬消耗過大的問題,在不改動業(yè)務數據的前提下,我們采用了數據壓縮的解決方案。
而壓縮是CPU密集型的操作,由于直播業(yè)務的實時性,不能簡單考慮壓縮比,在綜合平衡壓縮比、壓縮時延和壓縮CPU消耗后,調優(yōu)壓縮庫后實測的平均壓縮比達到6.7 : 1,數據量壓縮到原來的15%左右,這樣15625Mbps*15%=2344Mbps=2.29Gbps。單機萬兆網卡的帶寬容量,最多承載4.27萬的長連接下發(fā),雖然沒有達到5萬,基本也可以接受。
從全局帶寬來看,峰值也削減到不超過230Gbps,收益很明顯。

7.9 客戶端性能問題
進一步考慮,直播場景下,不僅是有較高的峰值消息量級,而是在直播過程中有持續(xù)的高消息量級壓力。這不僅對于服務端是壓力,對于客戶端來說也是個挑戰(zhàn)。
持續(xù)的高消息量級:
1)一方面客戶端在接收、展示等方面有明顯的壓力;
2)另一方面直播界面上過多過快的消息刷新,對于用戶體驗也是有害無益的。
所以:在綜合平衡用戶體驗和客戶端性能的基礎上,消息服務端增加了結合消息優(yōu)先級的分級頻控限速機制,單用戶客戶端并不需要承受每秒100條的壓力,削減每秒下發(fā)消息后,長連接單實例每秒下發(fā)5-8萬長連接,CPU和帶寬都是可以穩(wěn)定支持的。
7.10 實時消息問題
我們提供了基于消息優(yōu)先級的實時下發(fā)機制:
1)對于高優(yōu)消息可以立即觸發(fā)聚合下發(fā),不會增加聚合延時;
2)而對于普通中低優(yōu)消息,還是做延時聚合下發(fā)。
7.11 用戶在線問題
組播mcast機制的出發(fā)點,在百萬量級高并發(fā)在線的場景下,保障在線用戶的消息到達,允許不在線用戶接收消息的部分折損,付出合理的技術復雜度和成本,取得服務質量和性能平衡。
而針對在線用戶的消息到達,還有個關鍵問題是如何保障用戶的長連接在線。
為了提升長連接服務的接入穩(wěn)定性和可達性,我們在以下幾個方面做了優(yōu)化。
1)訪問點:
長連接服務在國內三大運營商的華北華東華南區(qū)域均部署了接入點入口。針對有部分國外用戶的直播場景,還增加了香港機房的獨立接入點入口。
2)HTTPDNS:
針對部分用戶的DNS劫持問題和解析錯誤問題,消息SDK接入了HTTPDNS服務并優(yōu)化本地緩存,形成多級域名解析保障體系,提升了域名解析的可靠性,減少了DNS劫持和錯誤率(見《百度APP移動端網絡深度優(yōu)化實踐分享(一):DNS優(yōu)化篇》)。
3)心跳優(yōu)化:
長連接的心跳是?;钐交畹闹匾侄危槍χ辈鼍皩崟r性高的特點,為了盡快發(fā)現(xiàn)長連接斷鏈,在組播mcastJoin后,長連接心跳也調整為間隔更短、服務端動態(tài)可控的智能心跳。
這樣在及時發(fā)現(xiàn)連接異常后,消息SDK可以快速主動重新建連。
4)斷鏈恢復:
在直播間用戶已加入組播mcast的情況下,如果長連接斷鏈,長連接服務端會主動或被動的觸發(fā)清除組播mcast成員。
而長連接重建連恢復時,直播業(yè)務層也需要監(jiān)聽連接恢復信號,重新加入組播mcast,以恢復組播mcast的消息通路。
7.12 小結一下
綜上所述,組播mcast機制:
1)有效的解決了百萬量級同時在線用戶的消息實時下發(fā)問題;
2)對于短時斷鏈和消息過多,允許部分消息的丟棄;
3)滿足了直播場景消息的設計目標。
組播mcast機制特點是:
1)消息服務和路由層壓力較輕,整體壓力只由長連接層承載,易于水平擴容;
2)基于延時聚合下發(fā),輔以壓縮限速,可以很好的解決下行QPS與帶寬的性能問題;
3)系統(tǒng)整體下行的QPS和帶寬是完全可控的。100W在線用戶的下行最大QPS是100W,500W在線用戶的下行最大QPS是500W。單實例的下發(fā)能力5-8萬QPS是穩(wěn)定的。因此,可以很容易判斷整體的系統(tǒng)容量,特殊場景是否需要擴容;
4)mcast機制雖然是針對直播場景提出的,但本身設計具有通用性,可以應用于其他需要實時在線大量用戶分組的消息推送場景。
8、基于組播mcast方案消息架構的進一步拓展
在組播mcast機制解決了百萬量級的在線用戶實時消息下發(fā)后,直播消息的場景不斷擴大,不斷有直播創(chuàng)新業(yè)務提出新的消息需求。
相應的,組播mcast的服務機制也需要與時俱進,不斷在深度和廣度上拓展優(yōu)化。以下重點介紹一下歷史消息和禮物消息。
8.1 直播間歷史消息的支持
對于剛進入直播間的用戶來說,需要看到一些最近的聊天記錄,以增強聊天互動氛圍并幫助了解直播的進展;對歷史聊天記錄感興趣額用戶,還可以追溯更多的消息歷史。這就產生了聊天歷史的需求。
為了支持這類歷史消息的需求,拓展方案是對于每個組播mcast申請開通一個組播公共消息信箱mcast-mbox服務。
邏輯是這樣的:
1)對于用戶消息和其他有持久化需要的消息,全部寫入這個消息信箱;
2)用戶可以指定組播mcastID,按時間區(qū)間和要拉取得消息條數,來獲取組播mcast的歷史消息。
下面補充說明一下消息信息的概念和應用。
什么是消息信箱服務的概念?
1)消息信箱內的一條消息msg,有唯一的消息標識符msgID;
2)一條消息msg,還包括有發(fā)送方信息、接收方信息、消息類型、消息內容等字段,此處可以暫時忽略;
3)每條消息可以設置過期時間,消息過期后不能訪問到;
4)每條消息可以設置已讀狀態(tài);
5)一個消息信箱mbox,有唯一的信箱標識符mboxID;
6)一個消息信箱mbox是一個容器,存儲有序的消息列表msgList;消息列表msgList按msgID排序的;
7)消息信箱服務,對指定信箱mbox支持單條消息或批量消息的寫入;
8)消息信箱服務,對指定信箱mbox支持基于msgID的單條消息或批量消息的查找;
9)消息信箱服務,對指定信息mbox支持從msgID-begin到msgID-end的范圍查找。
實際上,最常用的就是基于msgid范圍的消息拉取。這里的消息信箱服務是時間線timeline模型,有興趣的同學可以進一步參考時間線timeline模型的相關信息(見《現(xiàn)代IM系統(tǒng)中聊天消息的同步和存儲方案探討》一文中的“4、Timeline模型”一節(jié))。
8.2 直播間禮物消息的支持
禮物消息:?

禮物消息場景分析:
1)用戶送禮給主播,主播側需要盡快、可靠地收到禮物消息通知,才能及時的給予用戶反饋;
2)送出禮物的用戶,本地就可及時展示禮物效果,無消息通知強訴求;
3)直播間內其他用戶,需要收到禮物消息,以展示禮物效果,提升直播間互動氛圍,激發(fā)其他用戶送禮;
4)禮物消息涉及用戶訂單和購買行為,需要由服務端確認發(fā)出;
5)禮物消息優(yōu)先級明顯高于其他聊天消息、系統(tǒng)消息。
基于以上分析,直播消息提出以下技術拓展方案:
1)增加一個獨立的可靠消息組播mcast通道(如圖4中組播mcast-2),專供高優(yōu)可靠消息的收發(fā);與其他普通消息、系統(tǒng)消息在數據流層面隔離,減少相互干擾;
2)對于普通用戶側的端消息SDK,禮物消息組播mcast通道雖然是新增獨立通道,消息收發(fā)邏輯與普通消息組播mcast通道保持一致;
3)對于主播側,端消息SDK對于禮物消息組播mcast通道,需要支持推拉結合模式,以保障禮物消息的全部到達;即使有短暫的掉線,也需要取到全部禮物消息;
4)對于主播側,在極端情況下,如果長連接建連有異常,消息SDK可以通過短連接接口輪詢,來拉取禮物組播mcast信箱消息來兜底。
基于以上獨立的可靠消息組播mcast通道方案,在未剔除一些異常場景的情況下,如主播下線未關播、數據偶發(fā)打點丟失等,禮物消息的觸達率已達到99.9%以上。
8.3 直播消息其他方面的發(fā)展
在百度直播的發(fā)展歷程中,直播消息服務還面臨著許多其他基礎性問題和創(chuàng)新業(yè)務帶來的其他挑戰(zhàn)。
現(xiàn)在這些問題都有了較好的解決方案,以下列舉一些,供大家學習參考:
1)如何支持多種客戶端場景,安卓、iOS、H5、小程序、PC;
2)如何支持同一場直播的消息在百度APP和好看、全民、貼吧等矩陣APP的打通;
3)如何支持非登錄用戶:IM一般是支持登錄用戶,而直播場景也需要支持非登錄用戶;
4)長連接服務如果出了嚴重問題,是否有端獲取消息的降級通道;
5)直播消息審核的機審人審如何做,如何支持先發(fā)后審和先審后發(fā);
6)如何支持跨多個直播間的消息;
7)直播消息服務是如何支持創(chuàng)新業(yè)務的,如答題直播、直播帶貨、直播連麥等。
限于篇幅,以上問題在此不再做具體討論,有興趣同學歡迎探討。
9、回顧和展望
自百度直播上線以來幾年間,直播消息服務迎難而上,一路披荊斬棘為百度直播保駕護航,為百度直播提供了堅實的技術支撐和保障。
未來,在支持直播創(chuàng)新業(yè)務、更細粒度的消息分級服務、直播消息基礎服務的穩(wěn)定性和性能等方面,直播消息服務會繼續(xù)努力,夯實基礎,持續(xù)創(chuàng)新,以支持直播業(yè)務更好更快的發(fā)展。
附錄:更多相關文章
[1] IM群聊方面的文章:
《快速裂變:見證微信強大后臺架構從0到1的演進歷程(一)》
《如何保證IM實時消息的“時序性”與“一致性”?》
《IM單聊和群聊中的在線狀態(tài)同步應該用“推”還是“拉”?》
《IM群聊消息如此復雜,如何保證不丟不重?》
《微信后臺團隊:微信后臺異步消息隊列的優(yōu)化升級實踐分享》
《移動端IM中大規(guī)模群消息的推送如何保證效率、實時性?》
《現(xiàn)代IM系統(tǒng)中聊天消息的同步和存儲方案探討》
《關于IM即時通訊群聊消息的亂序問題討論》
《IM群聊消息的已讀回執(zhí)功能該怎么實現(xiàn)?》
《IM群聊消息究竟是存1份(即擴散讀)還是存多份(即擴散寫)?》
《一套高可用、易伸縮、高并發(fā)的IM群聊、單聊架構方案設計實踐》
《[技術腦洞] 如果把14億中國人拉到一個微信群里技術上能實現(xiàn)嗎?》
《IM群聊機制,除了循環(huán)去發(fā)消息還有什么方式?如何優(yōu)化?》
《網易云信技術分享:IM中的萬人群聊技術方案實踐總結》
《阿里釘釘技術分享:企業(yè)級IM王者——釘釘在后端架構上的過人之處》
《IM群聊消息的已讀未讀功能在存儲空間方面的實現(xiàn)思路探討》
>>?更多同類文章 ……
[2] 更多直播技術的文章:
《移動端實時音視頻直播技術詳解(一):開篇》
《移動端實時音視頻直播技術詳解(二):采集》
《移動端實時音視頻直播技術詳解(三):處理》
《移動端實時音視頻直播技術詳解(四):編碼和封裝》
《移動端實時音視頻直播技術詳解(五):推流和傳輸》
《移動端實時音視頻直播技術詳解(六):延遲優(yōu)化》
《理論聯(lián)系實際:實現(xiàn)一個簡單地基于html]5的實時視頻直播》
《實時視頻直播客戶端技術盤點:Native、html]5、WebRTC、微信小程序》
《Android直播入門實踐:動手搭建一套簡單的直播系統(tǒng)》
《淘寶直播技術干貨:高清、低延時的實時視頻直播技術解密》
《技術干貨:實時視頻直播首屏耗時400ms內的優(yōu)化實踐》
《新浪微博技術分享:微博實時直播答題的百萬高并發(fā)架構實踐》
《實時音頻的混音在視頻直播中的技術原理和實踐總結》
《七牛云技術分享:使用QUIC協(xié)議實現(xiàn)實時視頻直播0卡頓!》
《近期大熱的實時直播答題系統(tǒng)的實現(xiàn)思路與技術難點分享》
《P2P技術如何將實時視頻直播帶寬降低75%?》
《網易云信實時視頻直播在TCP數據傳輸層的一些優(yōu)化思路》
《首次披露:快手是如何做到百萬觀眾同場看直播仍能秒開且不卡頓的?》
《淺談實時音視頻直播中直接影響用戶體驗的幾項關鍵技術指標》
《技術揭秘:支持百萬級粉絲互動的Facebook實時視頻直播》
《移動端實時視頻直播技術實踐:如何做到實時秒開、流暢不卡》
《實現(xiàn)延遲低于500毫秒的1080P實時音視頻直播的實踐分享》
《淺談開發(fā)實時視頻直播平臺的技術要點》
《海量實時消息的視頻直播系統(tǒng)架構演進之路(視頻+PPT)[附件下載]》
《YY直播在移動弱網環(huán)境下的深度優(yōu)化實踐分享(視頻+PPT)[附件下載]》
《從0到1:萬人在線的實時音視頻直播技術實踐分享(視頻+PPT) [附件下載]》
《在線音視頻直播室服務端架構最佳實踐(視頻+PPT) [附件下載]》
>>?更多同類文章 ……
本文已同步發(fā)布于“即時通訊技術圈”公眾號。

▲ 本文在公眾號上的鏈接是:點此進入。同步發(fā)布鏈接是:http://www.52im.net/thread-3515-1-1.html,原文鏈接:點此進入