導讀:直播業務的核心功能有兩個,一個是實時音視頻推拉流,另外一個是直播間消息流的收發。本文主要介紹百度直播服務內的消息服務系統的設計實踐和演化。
redis
1、背景
直播間內用戶聊天互動,形式上是常見的IM消息流;但直播消息流不只僅是用戶聊天。除用戶聊天外,直播間內常見的用戶送禮物、進場、點贊、去購買、主播推薦商品、申請連麥等互動行爲的實時提醒,也是經過消息流下發的。此外,直播間關閉、直播流切換等特殊場景,也依賴消息流的實時下發。消息流能夠認爲是直播間內主播與用戶間實時互動和直播間實時控制的基礎能力。
2、直播消息1.0 - 奠基基礎
如何構建直播的消息系統,又有哪些挑戰須要解決,咱們來梳理一下。
2.1 直播消息場景分析
直播間內聊天消息,常常被類比於羣聊。羣聊是你們比較熟悉的即時通信場景,直播間內聊天和羣聊,兩者有類似性,但也有本質的區別。
對比兩者的特色:
- 同時參與人數不一樣:羣聊的參與人數上千人就是很大的羣了;但對於高熱度的大型直播場景,例如國慶、閱兵、春晚等,單直播間累計用戶是百萬甚至千萬量級的集合,同時在線人數可達數百萬人。
- 用戶與羣和直播間的關係不一樣:用戶進羣退羣,是相對低頻的操做,用戶集合相對固定,用戶進出的變動頻度不會特別高;而用戶進出直播間,是很是頻繁的,高熱度直播的單直播間每秒面臨上萬用戶的進出變動。
- 持續時間不一樣:羣聊創建後,聊天持續時間可能比較長,幾天到數月都有;而直播間大部分持續不超過幾個小時。
根據以上分析,提煉出兩個核心問題:
問題一:直播間內用戶的維護
小程序
- 單直播間每秒上萬用戶的進出變動;實際進入直播間峯值不超過2萬QPS,退出也不超過2萬QPS。
- 單直播間同時數百萬用戶在線
- 單直播間累計用戶達千萬量級
支持在線百萬、累積千萬兩個集合,每秒4萬QPS更新,有必定壓力,但有支持高讀寫性能的存儲應該能夠解決,例如redis。 後端
問題二:百萬在線用戶的消息下發
面對百萬在線用戶,上下行都有大量的消息,從直播用戶端視角分析:
緩存
- 實時性:若是消息服務端作簡單消峯處理,峯值消息的堆積,會形成總體消息延時增大,且延時可能產生很大的累積效應,消息與直播視頻流在時間線上產生很大的誤差,影響用戶觀看直播時互動的實時性。
- 端體驗和性能:端展現各種用戶聊天和系統消息,通常一屏不超過10-20條;若是每秒有超過20條的消息下發,端上展現的消息基本會持續刷屏;再考慮到有禮物消息的特效等;大量的消息,對端的處理和展現,帶來持續高負荷。因此,對於一個長時間觀看直播的用戶端來講,若是出現持續的大量消息,端的消息消費會有顯著的性能壓力,且過多消息會有累積效應。
因爲問題一不難解決,如下主要討論問題二。
2.2 直播消息設計目標
綜合考慮直播業務場景,對於消息服務的需求目標以下:
- 實時性方面,端和端的消息要達到秒級;
- 性能方面,消息服務能支持同一直播間內百萬以上用戶同時在線下發;
- 而對於峯值的過多消息,丟棄是合理適當的處理方式;
- 基於合理的端用戶體驗,單直播間內每秒消息數假設不超過N條。
如今,問題的核心是,如何作到把不超過N條的消息,在S秒內,下發到直播間內的百萬用戶,假設N<=20,S<=2。
2.3 普通羣聊壓力分析
2.3.1 普通羣聊消息收發分析
![圖片](http://static.javashuo.com/static/loading.gif)
△圖1:羣聊數據流及壓力點
首先,具體分析一下普通羣聊的消息收發流程:
架構
- 對於羣group-1,分配一個羣公共消息信箱group-mbox-1;
- 羣group-1內的用戶user-1,由手機端APP-1上發出消息msg-1;
- 服務端接收到消息msg-1,檢查user-1是否有權限,若有權限,將msg-1存儲到羣信箱group-mbox-1,生成相應msgID-1;
- 服務端查詢group-1對應的用戶列表groupUserList-1;
- 基於groupUserList-1拆分出全部獨立羣用戶:user-一、user-2。。。user-n;
- 對於每個用戶user-i來講,須要查詢用戶user-i的所在設備device-i-一、device-i-二、device-i-m(由於一個帳號可能登陸多個設備);
- 對於每一個設備device-i-j來講,長鏈接通道都會創建一個獨立的長鏈接connect-j以服務於該設備;但因爲connect-j是由端上APP-1鏈接到長鏈接服務的,具備動態性,因此,查詢device-i-j與connect-j的對應關係時,須要依賴一個路由服務route來完成查詢;
- 在查得connect-j後,能夠經過connect-j下發msg-1的通知groupmsg-notify-1;
- 若是用戶user-i正在使用device-i-j的手機端APP-1,用戶user-i就能夠當即從長鏈接connect-j上收到msg-1的通知groupmsg-notify-1;
- 在接收到groupmsg-notify-1後,手機端APP-1中的消息SDK根據端本地歷史消息記錄的最後一條消息latestMsg對應的消息ID即latestMsgID,來向服務端發起拉消息請求fetchMsg,拉取group-1中從latestMsgID+1到最新的全部消息;
- 服務端收到拉消息請求fetchMsg後,從group-mbox-1中取出latestMsgID+1到最新的全部消息,返回給端;若是消息過多,可能須要端分頁拉取;
- 端APP-1拉取到group-1中從latestMsgID+1到最新的全部消息,能夠作展現;在用戶在會話中閱讀後,須要設置全部新消息的已讀狀態或者會話已讀狀態。
2.3.2 普通羣聊主要壓力
若是徹底重用普通羣聊消息的下發通知到端拉取的全過程,對於user-1發的一條消息msg-1,若是須要支持一個實時百萬量級的羣消息,大概有如下幾個每秒百萬量級的挑戰:
首先,秒級拆分出用戶列表groupUserList-1,須要秒級讀出百萬的用戶列表數據,對於存儲和服務是第一個百萬級挑戰。
第二,對於拆分出羣中的全部獨立用戶user-i,須要秒級查詢出百萬量級的device-i-j,對於存儲和服務是第二個百萬級挑戰。
第三,對於全部device-i-j,經過動態路由服務route,須要秒級查詢出百萬量級的connect-j,對於存儲和服務是第三個百萬級挑戰。
第四,對於經過長鏈接connect-j下發時,須要支持秒級下發百萬量級的羣消息通知groupmsg-notify-1到對應的connect-j上,對於長鏈接服務是個百萬級的挑戰。
第五,對於收到消息通知的全部端APP-1,須要支持百萬QPS端從服務端拉取消息請求fetchMsg,對於消息信箱服務,這是也是一個百萬量級的挑戰;考慮到實際各端latestMsgID可能不一樣,可能的優化方式會更復雜一些,帶來的性能影響會更大。
第六,若是在絕大多數用戶是在線聊天的場景,設置已讀狀態也會有百萬量級QPS對服務端的壓力。
顯然,徹底重用羣聊的消息流程,對消息服務和長鏈接服務帶來的壓力是巨大的。
2.3.3 普通羣聊優化方案
![圖片](http://static.javashuo.com/static/loading.gif)
△圖2:羣聊數據流優化後壓力點
如今,咱們來分析以上每一個百萬量級的挑戰,是否有優化的空間。
併發
- 對於①拆分用戶列表和②查詢用戶對應設備,若是存儲上將兩者合併集中起來,也就是優化直播間內用戶列表的存儲,擴展設備信息,能夠減小一次user->device的百萬QPS查詢,能夠優化。
- 對於④下行通知和⑤端拉取fetchMsg的可靠消息拉取模式,考慮到直播消息容許部分折損丟棄,能夠只作單向消息下發,而不作拉取,對於大部分鏈接保持在線的用戶,也是能夠接受的。因此能夠優化,只保留下行通知(包含消息體),而捨棄端拉取。
- 對於⑥消息設置已讀,直播場景下能夠考慮簡化捨棄。
如上優化後,減小了②⑤⑥三個百萬量級壓力請求,但還有①拆分用戶列表③動態路由查詢④長鏈接下發,這三個百萬量級步驟須要處理。
對於①拆分用戶列表,支持百萬量級用戶列表查詢,比較常規的思路是支持基於羣groupID的批量查詢,例如一次能夠查出100個用戶,1萬QPS查詢就能夠支持到百萬;基於羣groupID把用戶數據的存儲,分散到多個主從實例和分片上,控制好打散粒度不出現熱點,基本能作到,只是存儲資源可能消耗較多。
對於③動態路由查詢,表面上看,面臨的問題與①相似,但卻有些不一樣。由於羣的用戶列表,是基於羣groupID作key,創建一個表或多個打散的表;而device-i-j的查詢是徹底分散的,也是須要批量查詢能力,可是徹底分散的設備信息查詢,不能只針對特定key作優化,須要動態路由服務支持總體上達到百萬QPS的查詢性能。
對於④長鏈接服務下發,因爲長鏈接服務不依賴外部的存儲服務,若是總體要支持百萬量級的下發能力,若長鏈接單實例能支持1萬的下發能力,總體上100個實例就能支持到百萬量級下發。
基於以上分析,支持百萬量級的消息下發,初見曙光。彷佛只要優化好用戶列表、動態路由的存儲/查詢和長鏈接的容量擴容,但全部的前提是須要消耗大量存儲和機器資源。考慮到直播業務的實際狀況,現實不容樂觀:
一方面,平時沒有熱點直播時,可能單場直播併發在線用戶數峯值不超過1萬人,甚至不到1000;在業務初期,總體直播在線用戶峯值可能也不超過10萬。這就意味着,爲了支持百萬量級的峯值,資源總體上有幾十倍的冗餘。
另外一方面,若是忽然來了一場熱度很是高的直播,可能須要支持的不僅是100萬量級消息下發,多是500萬以上的量級(例如國慶閱兵、春晚等)。這樣的話,每次大型直播得提早預估可能的在線用戶峯值,若是超過當前設計容量,須要對①用戶列表③動態路由查詢④長鏈接服務,分別擴容和壓測;或者在可接受的狀況下,作服務降級或拒絕服務。
而實際上,在線用戶峯值量級很難估計準確,這樣會形成實際資源利用率很低,擴縮容的操做頻繁,運維成本高。是否選擇這個方案,也是很使人糾結。
2.3.4 普通羣聊多羣組方案
也有人提過拆分多個羣組的方案,例如,若是一個羣組最多支持1萬用戶,開100個羣就能夠支持一百萬用戶;再創建一個虛擬羣,將這100個羣關聯起來,彷佛可行。
但若是仔細分析,會發現以上提到的幾個問題①拆分用戶列表③動態路由查詢④長鏈接下發,高壓力依然存在,仍是不可避免。
除此以外,多羣組還會引入其餘問題:
問題一:多羣組消息不一樣步。若是兩個用戶在一塊兒看直播,而所屬羣不一樣,看到的消息會徹底不一樣。
問題二:直播場景用戶是動態進出的,也就是說羣組成員很是不穩定,在線用戶峯值波動也比較大。若是是根據在線人數增加,動態新開羣組,可能第一個羣用戶已經不少了,第二個羣剛開始用戶比較少;或者,在峯值期間開了比較多的羣,隨着熱度下降用戶離開,用戶變得分散,一些羣的用戶可能較稀少,聊天互動較少,這時須要縮容合併羣。如何平衡多個羣的用戶,達到好的業務效果,也是比較難作的。
基於以上分析,咱們並無選擇多羣組方案。
2.4 組播mcast方案
支持實時高併發百萬量級同時在線用戶的直播消息架構,組播mcast方案的提出及演化。
2.4.1 跳出原有框架思考
是否要採用以上基於羣聊的優化方案,仍是能夠另闢蹊徑?
先暫時拋開羣收發消息流程,對於消息下發來講,若是必定要說一個步驟是必不可少的,那必定是長鏈接下發這步了。沒有經過長鏈接下發,消息就沒法最終到達用戶;固然有人說輪詢拉取也能夠替代長鏈接下發,來獲取消息,但顯然輪詢拉取的性能壓力和實時性與長鏈接下發相比差不少,故不在討論範圍。
若是能簡化爲,給長鏈接服務下發消息時指定一個相似的groupID,長鏈接服務能直接拆分到全部羣組用戶相關的長鏈接connect-j,就能夠省略掉用戶列表拆分和動態路由查詢的百萬量級查詢。
這樣的話,消息下發的壓力將主要由長鏈接服務來承受,服務端也不須要對多個系統擴容,直播消息的優化可能會大爲簡化。
根據這個思路,至關於在長鏈接服務中,對鏈接connect也創建羣組的概念。基於鏈接組的設想,咱們設計了一套長鏈接的組播mcast機制。
2.4.2 長鏈接組播mcast基本概念
- 每一個長鏈接組播mcast有全局惟一的標識mcastID。
- 長鏈接組播mcast支持建立、刪除、修改、查詢等管理操做。
- 長鏈接組播mcast是若干長鏈接在線用戶的鏈接connect的集合。
- 一個用戶user-i在設備device-i-j上,對於特定應用APP-k來講,創建惟一的一個長鏈接connect-j-k;(此處暫時不區別登陸用戶和非登陸用戶)。
- 長鏈接組播mcast與組內長鏈接connect-j-k的關係維護,不須要額外的獨立存儲,是維護在每一個長鏈接服務的實例上。
2.4.3 長鏈接組播mcast的路由概念
組播mcast-m的路由route-m,是一個長鏈接服務實例的集合LcsList,記錄了全部加入mcast-m的長鏈接connect-i所在長鏈接服務實例lcs-j。
2.4.4 長鏈接組播mcast路由的記錄維護
加入組播mcast:
app
- 客戶端調用消息sdk加入mcast-m。
- 消息sdk經過長鏈接,發出上行請求mcastJoin(mcast-m)。
- 業務層收到來自長鏈接實例lcs-i上的鏈接connect-i的mcastJoin請求,校驗mcast-m的合法性。
- 業務層請求路由層創建基於組播mcast-m的組播路由mcastRoute-m,將長鏈接實例lcs-i加入組播路由mcastRoute-m中。
- 業務層請求長鏈接服務層,請求mcastJoin所在長鏈接實例lcs-i,將請求所在鏈接connect-i加入到mcastConnectList-m中。
離開組播mcast,與加入組播mcast基本相似,由客戶端調用消息sdk離開mcast-m,發出上行請求mcastLeave(mcast-m),長鏈接服務端更新路由和mcastConnectList-m信息。
2.4.5 組播mcast消息推送
△圖3:組播mcast數據流及壓力點
基於組播mcast的長鏈接消息推送過程,是一個1:M * 1:N的擴散放大過程,具體過程描述以下:
框架
- 一條消息msg-1推送,目的地是ID爲mcast-m組播;
- 後端業務模塊根據目的mcast-m,作一致性hash選擇出mcast路由分發模塊實例mcastRouter- i,發送msg-1到mcastRouter-i;
- mcast分發路由模塊實例mcastRouter-i,根據mcast-m的組播路由mcastRoute-m,查找所對應的接入實例路由記錄列表mcastLcsList-m,拆分出mcast-m全部的長鏈接接入實例lcs-1..lcs-M,分別併發發送msg-1到長鏈接實例上;
- 一個長鏈接服務實例lcs-j,收到消息msg-1推送後,根據組播mcast-m查找組播鏈接列表mcastConnectList-m,查出mcast-m內全部的鏈接connect-m-1..connect-m-N,併發推送msg-1到消息客戶端sdk-m-1..sdk-m-N;
- 消息客戶端sdk-m-o收到msg-1後,遞交給上層業務(例如直播sdk)。
2.4.6 組播mcast機制的性能評估
如今分析一下以上的組播mcast機制的性能壓力:
運維
- 組播mcast的路由維護,主要壓力在於mcastJoin和mcastLeave,而Join的量級峯值請求很難超過2萬qps;訪問壓力比百萬低兩個數量級。
- 組播mcast的消息推送流程,在一級路由mcastRoute拆分到長鏈接實例時,通常在幾十到百量級,成本很低。
- 組播mcast在長鏈接單實例內的消息推送,是單進程內的多鏈接併發發送,經優化後線上實測,在單實例保持25W長鏈接的狀況下,單實例壓測可達8Wqps的mcast穩定下發,保守按5Wqps容量評估;多個長鏈接實例間,是徹底的併發,能夠較容易的水平擴容。
- 綜上可知,對於100Wqps的下發,20個長鏈接實例就能夠徹底負荷(20*5W=100W),且有必定裕量。若是500Wqps的下發,也不超過100實例;1000W的下發,若是以8W單實例較大的負荷承載,125實例就能夠支持。
容量評估(實例數) |
單實例1萬qps |
單實例5萬qps |
單實例8萬qps |
100萬長鏈接 |
100 |
20 |
12.5 |
500萬長鏈接 |
500 |
100 |
62.5 |
1000萬長鏈接 |
1000 |
200 |
125 |
看上去,基於以上組播mcast機制,咱們創建了一套高效的支持百萬量級QPS的長鏈接下發機制,當前長鏈接服務的容量就能夠支持,基本不用擴容。可是否能徹底知足直播業務場景需求,還須要進一步討論。
2.4.7 消息峯值問題
對於每秒1條消息,擴散到100W用戶,甚至500W用戶,以上組播mcast機制彷佛都能應對。
但直播間內消息的實際狀況是,熱門的直播每秒用戶上行聊天消息會有不少,除聊天消息外,直播間還有人數、進場、點贊、分享等按期和不按期發送的不少種類系統消息。
若是假設每秒峯值有100條各種消息,100W*100=1億,簡單按單實例5Wqps算,須要2000個實例才能支持,雖然比老的羣聊系統應該好不少,但系統仍是遇到大量資源冗餘或應對峯值須要大量擴容的老問題。是否能有更好的解決方式?
ide
2.4.7.1 延時聚合
這裏咱們考慮常見的一個優化思路,是經過批量聚合的模式來提升系統性能。若是將這100條消息,每秒聚合打包一次來統一下發,QPS仍是100W,長鏈接系統的下發QPS不變,但每秒下發消息量級能夠達到1億,這個聚合方案實測是可行的。聚合模式,咱們付出的成本是消息時延的上升,1秒的聚合平均時延增長500ms,用戶體驗損失不算大,但系統下發消息量級能夠提高百倍,綜合評估成本收益來看是合理的。考慮到直播的實際場景,大多數場景下秒級的聚合和時延是能夠接受的。
2.4.8 消息帶寬問題
聚合延時下發,長鏈接單實例QPS問題解決了,隨之而來的是,長鏈接單實例下發的帶寬壓力問題。例如,長鏈接單實例須要下發10000長鏈接時,每秒100消息,消息平均2K字節,實際帶寬爲2K*100*10000*8=15625Mbps,這已經超過單物理機的萬兆網卡的帶寬容量。
另外一方面,從全局帶寬來看,也高達1.5Tbps,帶寬資源對於機房出口也會帶來壓力,這樣的帶寬成本太高,須要削減帶寬使用或有更好的替代方案。
面對下發數據量帶寬消耗過大的問題,在不改動業務數據的前提下,咱們採用了數據壓縮的解決方案。而壓縮是CPU密集型的操做,因爲直播業務的實時性,不能簡單考慮壓縮比,在綜合平衡壓縮比、壓縮時延和壓縮CPU消耗後,調優壓縮庫後實測的平均壓縮比達到6.7 : 1,數據量壓縮到原來的15%左右,這樣15625Mbps*15%=2344Mbps=2.29Gbps;單機萬兆網卡的帶寬容量,最多承載4.27萬的長鏈接下發,雖然沒有達到5萬,基本也能夠接受。
從全局帶寬來看,峯值也削減到不超過230Gbps,收益很明顯。
帶寬對比 |
壓縮前 |
壓縮後 |
單機10000長鏈接 |
15.26 Gbps |
2.29 Gbps |
全局100萬長鏈接 |
1.49 Tbps |
229 Gbps |
全局500萬長鏈接 |
7.45 Tbps |
1.12 Tbps |
2.4.9 客戶端性能問題
進一步考慮,直播場景下,不只是有較高的峯值消息量級,而是在直播過程當中有持續的高消息量級壓力;這不只對於服務端是壓力,對於客戶端來講也是個挑戰。持續的高消息量級,一方面,客戶端在接收、展現等方面有明顯的壓力;另外一方面,直播界面上過多過快的消息刷新,對於用戶體驗也是有害無益的。
因此,在綜合平衡用戶體驗和客戶端性能的基礎上,消息服務端增長告終合消息優先級的分級頻控限速機制,單用戶客戶端並不須要承受每秒100條的壓力,削減每秒下發消息後,長鏈接單實例每秒下發5-8萬長鏈接,CPU和帶寬都是能夠穩定支持的。
2.4.10 實時消息問題
咱們提供了基於消息優先級的實時下發機制,對於高優消息能夠當即觸發聚合下發,不會增長聚合延時;而對於普通中低優消息,仍是作延時聚合下發。
2.4.11 用戶在線問題
組播mcast機制的出發點,在百萬量級高併發在線的場景下,保障在線用戶的消息到達,容許不在線用戶接收消息的部分折損,付出合理的技術複雜度和成本,取得服務質量和性能平衡。
而針對在線用戶的消息到達,還有個關鍵問題是如何保障用戶的長鏈接在線。
爲了提高長鏈接服務的接入穩定性和可達性,咱們在如下幾個方面作了優化。
長鏈接服務在國內三大運營商的華北華東華南區域均部署了接入點入口;針對有部分國外用戶的直播場景,增長了香港機房的獨立接入點入口。
針對部分用戶的DNS劫持問題和解析錯誤問題,消息SDK接入了HTTPDNS服務並優化本地緩存,造成多級域名解析保障體系,提高了域名解析的可靠性,減小了DNS劫持和錯誤率。
長鏈接的心跳是保活探活的重要手段,針對直播場景實時性高的特色,爲了儘快發現長鏈接斷鏈,在組播mcastJoin後,長鏈接心跳也調整爲間隔更短、服務端動態可控的智能心跳。這樣在及時發現鏈接異常後,消息SDK能夠快速主動從新建連。
在直播間用戶已加入組播mcast的狀況下,若是長鏈接斷鏈,長鏈接服務端會主動或被動的觸發清除組播mcast成員。而長鏈接重建連恢復時,直播業務層也須要監聽鏈接恢復信號,從新加入組播mcast,以恢復組播mcast的消息通路。
2.4.12 組播mcast小結
綜上所述,組播mcast機制,有效的解決了百萬量級同時在線用戶的消息實時下發問題;對於短時斷鏈和消息過多,容許部分消息的丟棄;知足了直播場景消息的設計目標。
組播mcast機制特色是:
- 消息服務和路由層壓力較輕,總體壓力只由長鏈接層承載,易於水平擴容。
- 基於延時聚合下發,輔以壓縮限速,能夠很好的解決下行QPS與帶寬的性能問題。
- 系統總體下行的QPS和帶寬是徹底可控的。100W在線用戶的下行最大QPS是100W,500W在線用戶的下行最大QPS是500W。單實例的下發能力5-8萬QPS是穩定的。所以,能夠很容易判斷總體的系統容量,特殊場景是否須要擴容。
- mcast機制雖然是針對直播場景提出的,但自己設計具備通用性,能夠應用於其餘須要實時在線大量用戶分組的消息推送場景。
3、直播消息2.0 - 持續發展
在組播mcast機制解決了百萬量級的在線用戶實時消息下發後,直播消息的場景不斷擴大,不斷有直播創新業務提出新的消息需求。相應的,組播mcast的服務機制也須要與時俱進,不斷在深度和廣度上拓展優化。如下重點介紹一下歷史消息和禮物消息。
3.1 歷史消息
對於剛進入直播間的用戶來講,須要看到一些最近的聊天記錄,以加強聊天互動氛圍並幫助瞭解直播的進展;對歷史聊天記錄感興趣額用戶,還能夠追溯更多的消息歷史。這就產生了聊天曆史的需求。
爲了支持這類歷史消息的需求,解決方案是對於每一個組播mcast申請開通一個組播公共消息信箱mcast-mbox服務。
- 對於用戶消息和其餘有持久化須要的消息,所有寫入這個消息信箱。
- 用戶能夠指定組播mcastID,按時間區間和要拉取得消息條數,來獲取組播mcast的歷史消息。
補充說明一下消息信息的概念和應用。
3.1.1 消息信箱服務概念
- 消息信箱內的一條消息msg,有惟一的消息標識符msgID。
- 一條消息msg,還包括有發送方信息、接收方信息、消息類型、消息內容等字段,此處能夠暫時忽略。
- 每條消息能夠設置過時時間,消息過時後不能訪問到。
- 每條消息能夠設置已讀狀態。
- 一個消息信箱mbox,有惟一的信箱標識符mboxID。
- 一個消息信箱mbox是一個容器,存儲有序的消息列表msgList;消息列表msgList按msgID排序的。
- 消息信箱服務,對指定信箱mbox支持單條消息或批量消息的寫入。
- 消息信箱服務,對指定信箱mbox支持基於msgID的單條消息或批量消息的查找。
- 消息信箱服務,對指定信息mbox支持從msgID-begin到msgID-end的範圍查找。
實際上,最經常使用的就是基於msgid範圍的消息拉取;這裏的消息信箱服務是時間線timeline模型,有興趣的同窗能夠進一步參考時間線timeline模型的相關信息。
3.2 禮物消息
△圖4:禮物消息
禮物消息場景分析:
- 用戶送禮給主播,主播側須要儘快、可靠地收到禮物消息通知,才能及時的給予用戶反饋。
- 送出禮物的用戶,本地就可及時展現禮物效果,無消息通知強訴求。
- 直播間內其餘用戶,須要收到禮物消息,以展現禮物效果,提高直播間互動氛圍,激發其餘用戶送禮。
- 禮物消息涉及用戶訂單和購買行爲,須要由服務端確認發出。
- 禮物消息優先級明顯高於其餘聊天消息、系統消息。
基於以上分析,直播消息提出如下技術方案:
- 增長一個獨立的可靠消息組播mcast通道(如圖4中組播mcast-2),專供高優可靠消息的收發;與其餘普通消息、系統消息在數據流層面隔離,減小相互干擾;
- 對於普通用戶側的端消息SDK,禮物消息組播mcast通道雖然是新增獨立通道,消息收發邏輯與普通消息組播mcast通道保持一致;
- 對於主播側,端消息SDK對於禮物消息組播mcast通道,須要支持推拉結合模式,以保障禮物消息的所有到達;即便有短暫的掉線,也須要取到所有禮物消息;
- 對於主播側,在極端狀況下,若是長鏈接建連有異常,消息SDK能夠經過短鏈接接口輪詢,來拉取禮物組播mcast信箱消息來兜底。
基於以上獨立的可靠消息組播mcast通道方案,在未剔除一些異常場景的狀況下,如主播下線未關播、數據偶發打點丟失等,禮物消息的觸達率已達到99.9%以上。
3.3 直播消息其餘方面的發展
在百度直播的發展歷程中,直播消息服務還面臨着許多其餘基礎性問題和創新業務帶來的其餘挑戰。如今這些問題都有了較好的解決方案,如下列舉一些,供你們學習參考:
- 如何支持多種客戶端場景,安卓、iOS、H五、小程序、PC。
- 如何支持同一場直播的消息在百度APP和好看、全民、貼吧等矩陣APP的打通。
- 如何支持非登陸用戶。IM通常是支持登陸用戶,而直播場景也須要支持非登陸用戶。
- 長鏈接服務若是出了嚴重問題,是否有端獲取消息的降級通道。
- 直播消息審覈的機審人審如何作,如何支持先發後審和先審後發。
- 如何支持跨多個直播間的消息。
- 直播消息服務是如何支持創新業務的,如答題直播、直播帶貨、直播連麥等。
限於篇幅,以上問題在此再也不作具體討論,有興趣同窗歡迎直接聯繫探討。
4、回顧展望
自百度直播上線以來幾年間,直播消息服務迎難而上,一路披荊斬棘爲百度直播保駕護航,爲百度直播提供了堅實的技術支撐和保障。
將來,在支持直播創新業務、更細粒度的消息分級服務、直播消息基礎服務的穩定性和性能等方面,直播消息服務會繼續努力,夯實基礎,持續創新,以支持直播業務更好更快的發展。
推薦閱讀
|萬象:百度的海量多媒體信息處理系統
---------- END ----------
百度架構師
百度官方技術公衆號上線啦!
技術乾貨 · 行業資訊 · 線上沙龍 · 行業大會
招聘信息 · 內推信息 · 技術書籍 · 百度周邊
歡迎各位同窗關注!