本文由「聲網Agora」的RTC開發者社區整理。php
本文將分享新浪微博系統開發工程師陳浩在 RTC 2018 實時互聯網大會上的演講。他分享了新浪微博直播互動答題架構設計的實戰經驗。其背後的百萬高併發實時架構,值得借鑑並用於將來更多場景中。本文正文是對演講內容的整理,請繼續往下閱讀。html
另外,即時通信網整理的直播答題相關文章有:小程序
《近期大熱的實時直播答題系統的實現思路與技術難點分享》微信小程序
《2018新「風口」——直播答題應用原理解析》性能優化
新浪微博團隊分享的:《新浪微博技術分享:微博短視頻服務的優化實踐之路》一文,您也可能感興趣。服務器
(本文同步發佈於:http://www.52im.net/thread-2022-1-1.html)微信
首先,以下圖所示,這是一個傳統的直播頁面。它的主頁面是直播的音視頻流,下面顯示的是消息互動,包括評論、點贊和分享。什麼是直播答題呢?網絡
直播答題其實本質上仍是一個直播的場景,只是引入了答題的互動方式。主持人能夠經過口令控制客戶端的行爲,好比控制發題。同時,直播答題經過獎金激勵,帶動更多用戶參與進來。在每一次答題以後,會將數據實時展現出來。下圖展現的是直播答題的流程,中間的部分是會重複進行的環節。架構
直播答題的核心需求用一句話就能夠歸納:海量用戶同時在線的場景下,確保用戶的答題畫面能展示,在直播過程當中流暢地參與答題,最終分到獎金。併發
這一句話中有三個關鍵點,分別對應了不一樣的技術要求:
第一個:就是「海量用戶同時在線」。海量用戶帶來的就是海量的數據。在這個場景下第一個用戶高峯出如今活動開始前,海量的用戶會在幾分鐘內加入房間。在直播進行中,答題的十秒倒計時內,海量用戶會同時提交答案,會產生海量的答題消息,包括咱們互動與題目結果的消息,因此下發、上傳雙向都會出現高併發。這就考驗咱們對海量數據高併發的處理能力。
第二個:關鍵點是「答題畫面可以展現」,這是很是基礎且首要的需求,由於用戶參與答題,若是畫面都展現不出來,那麼這場遊戲就無法進行下去了。每一輪答題均可能淘汰一批用戶,淘汰答錯題的用戶是正常的,但若是是由於未能展現出答題畫面而淘汰,那就是技術問題。其技術難點在於海量題目的下發成功率要有保證,給技術提出的對應要求就是服務的可靠性。
最後一個:是「流暢地參與答題」,這與用戶體驗相關,每一輪答題時間間隔很短,一旦錯過一道題的答題時間,用戶就無法完成這個遊戲,因此要保證消息下發後,10秒內讓用戶收到而且正常展現。同時,每一輪答題後,主持人須要馬上看到答題數據,包括有多少用戶答對,有多少用戶使用了復活卡等。這給咱們帶來的是對海量數據進行實時下發、實時統計的挑戰。
咱們基於微博直播的技術現狀,設計了一個方案。以下圖所示,這是咱們微博直播互動的架構圖。左側是微博的基礎設施服務,基本上都是自研的,好比最核心的短連使用的是自研的 wesync 協議,支持SSL,是支撐百萬互動消息下發的核心服務之一。長連維護消息通道可動態擴容,海量用戶同時涌入後會進行容量的計算,對咱們的資源進行擴縮容。
在直播答題方案設計(下圖)中,最核心的就是解決答題信令通道的選擇問題。咱們想到了三個方案來解決。
方案一:輪詢
客戶端不斷進行請求,由服務端控制時間窗口,到時間咱們開放請求,結果返回。優勢是實現簡單。缺點在於大量無用請求會消耗大量帶寬資源,給服務端帶來持續性的壓力。並且,題目到達時間與音視頻流到達時間難以保持一致。
方案二:複用音視頻通道
咱們能夠在音視頻流裏面直接加入題目的信息。在主持人口令位置插入題目消息。客戶端播放音視頻流,收到題號數據的時候,直接把題目給展現出來。這個方案的特色就是題目展現的時間能和主持人口令一致,也就是說用戶是感知不到時間差的,體驗很是好。缺點是太依賴於音視頻流,一旦出現網絡抖動,或者直播流中斷,用戶可能會收不到題目,這個遊戲就無法繼續下去了。
方案三:複用互動通道
直播有音視頻流通道和互動通道,題目使用互動通道獨立下發。它的特色是題目下發不依賴於音視頻流,它的通道是獨立的,不受直播流的影響,即便直播中斷了,哪怕是黑屏,咱們也能夠把題目的畫面展現給用戶。缺點也是同樣,由於它並非跟音視頻在一個通道,因此它們二者時間難以保持一致。
咱們從接入難度、擴展性和音視頻同步三方面,對三個方案進行了對比。針對以上三個方案,咱們最終使用方案三。首先要保證答題不受直播流信號的影響。咱們如今微博直播現有的架構上可以支持千萬級消息的下發,咱們把答題信息放到互動通道下發,這是咱們有能力支持的。答題和互動的上行消息由短連服務支撐,在發題以及結果展現信息的時候,咱們直接經過主動推送,通過廣播消息,經過長連最終發給用戶。也就是說整個答題就直接採用了互動的通道,與音視頻流徹底隔離開來。
針對實時性、可靠性和高併發,三個典型的問題,咱們也有不一樣的解決方法。
實時性問題主要體如今兩方面,一個是答題畫面的實時展示,另外一個是海量數據的實時統計。
直播流通過採編設備發給用戶客戶端是有延時的,中間通過編解碼,到達客戶端的時間和主持人發出口令時間,有一個時間間隔。咱們採用互動通道的時候,這兩個時間咱們是不容易作同步的。客戶端收到題目和視頻流最終到達的時間會出現不一致的狀況。
咱們看下圖,當主持人 T0 時間發題,用戶在 T2 時間有可能才收到這個視頻流。若是咱們 T0 的時間進行發題,在 T1 的時間題目就到用戶客戶端了。問題在於咱們如何抹去 T2-T1 的時間差。對於用戶體驗來講,咱們在 T1 把題目畫面展現出來,在下一秒才能聽到主持人說「請聽題」,這體驗確定很差。
咱們的處理方式是在音視頻每隔一幀,或者必定幀數內,插入服務器的時間戳。同時,咱們在下發的消息體內也埋入服務器的時間戳。客戶端播放音視頻流的時候,到達相應的時間戳時,把跟這個時間戳相匹配的消息在頁面上渲染出來,也就是展現出了答題的畫面。經過使用統一時間戳進行對標,就抹平了視頻與題目的時間差。
咱們每一輪答題結束的時候,都要統計用戶的答題狀態,好比用戶答案是否正確,用戶是否復活,以及他是否有復活卡。當這些邏輯都放在一塊兒須要處理,而且又是在一個海量數據場景下時,就變得很是複雜了。
另外一方面,每一輪的答題只有發題和展現答案兩個指令。主持人在發題時會說題目是什麼,最終說出結果是什麼。沒有單獨指令觸發告訴服務器端何時進行數據處理。並且,海量數據須要獲得快速的計算。
把海量用戶產生的海量數據一次性的獲取出來,這是不現實的,耗費資源至關巨大,因此咱們的思路就是化整爲零,作並行處理。
首先,當發題指令到達服務端的時候,咱們按照必定的規則對用戶進行細粒度的拆分。同時根據倒計時和流延時等等時間綜合考慮,可以計算出咱們何時才能開始進行數據處理。而後將剛纔作好的用戶分片,封裝成任務分片,放在延時隊列當中。到達這個執行時間的時候,由咱們處理機的機羣拉取這個任務,只有在執行時間纔會去處理這個任務,不會出現用戶答案沒有提交上來,咱們就開始計算了。因此不會有將一部分用戶漏掉的情況。
處理機拉到用戶的任務分片時,根據用戶選擇、狀態,以及長連的地址,咱們對用戶的消息整合。由於有海量的用戶,因此體量巨大,可是答案選擇每每只有 A、B、C、D 四種,針對答案咱們能夠作一個分組,好比選 A 用戶有多少,選 B 用戶有多少。咱們把單獨消息進行合併,選A的用戶作爲一個集合。
也就是說這一個消息體其實包含了不少用戶的消息,從消息體量上,咱們進行降量,把小的消息合成成一個消息體,把一個消息體發給咱們長鏈接的服務,長鏈接收到這個消息體的時候再進行拆分。它相似於消息的一個包,咱們把它按照用戶的維度進行拆分,好比用戶選擇了什麼答案,它是否使用過復活卡,以及它的狀態,進行拆分後,最終下發給用戶。這樣在前面進行拆,在後面進行合,合完以後再拆一遍,這是咱們解決海量數據實時計算的思路。
剛纔咱們提到,用戶若是在弱網狀況下發生丟包,咱們推送的消息有可能他無法收到,他一旦收不到消息,整個答題沒有辦法進行,有可能致使他在這一輪就被淘汰了。咱們的解決方案是實現更穩定更快速的自動重連。雖然用戶的網絡環境是咱們沒有辦法去保證的,但咱們能夠更快速發現他和咱們長連服務器斷連,並進行更快速的重連。
同時,在答題倒計時內咱們無條件對題目消息進行重傳。例如咱們 T0 的時候發現用戶斷連,他在 T1 的時候,下發的題目收不到,而後咱們在 T2 進行重連,在 T3 進行無條件重傳的時候保證他收到這個題目。咱們在消息體埋了一個最遲的展示時間,到這個時間後客戶端必定會把題目展現出來,保證他就算直播流斷了,咱們也能夠正常答題。面對黑屏的場景咱們也能夠完成答題的遊戲。
每道題目下發後有一個10秒倒計時。假設有百萬用戶在線,在10秒以內均可以提交完答案,用戶提交答案大概集中在第3至第6秒之間,QPS 峯值預估會有30萬。其次,咱們保證用戶答案在短期都能提交,由於它是有時間限制的,若是咱們作了削峯限流,他就會錯過答題的時間窗口。因此咱們不能對請求作削峯限流。
咱們的解決方案就是用戶請求處理快速返回時,把重邏輯日後延,前面上行請求只是保證輕邏輯,讓它能夠迅速返回。
同時,在資源層,咱們對數據進行處理時,把用戶提交的請求作一個合併,交給獨立的資源池進行批量提交。咱們的設計方案有一個閾值,當遇到不可控,好比負荷達到咱們設計的閾值時,咱們有自動隨機重試的機制,保證用戶把答案均可以提交上來。對於重試請求咱們作針對性的時間補償,這樣保證流量達到咱們負載的時候,答題請求也能夠提交上來。
一條題目消息,會被複制N份後下發給用戶。百萬用戶產生的答案消息是海量的,對於千萬級消息實時下發的系統來講,訂閱端的網絡帶寬壓力也是巨大的。以下圖所示,消息出口的帶寬消耗很是大,由於咱們是針對海量用戶的鏈接。
咱們的解決方法有兩方面。第一就是針對海量消息下發,對消息進行體積上的壓縮,減小消息傳輸的冗餘。壓縮消息的時候咱們採用了一個私有協議,咱們儘可能壓縮裏面無用的東西,減少傳輸冗餘,減少帶寬的消耗。
第二個是消息降量,咱們根據用戶的答案進行分組,按照分組把這些消息進行合併,由原來的一條消息都要推送一次,轉變成下發一個消息集合。同時,咱們提高消息的吞吐量,採用中間件的集羣,進行多端口並行的下發。
直播答題場景有一個特別明顯的特徵,它不像咱們上線其它功能或者接口,咱們能夠進行灰度放量。直播答題一上線,就是全量,沒有能經過灰度放量發現問題的過程。因此咱們對系統服務承載能力須要有一個量化的評估。
咱們的處理方式就是進行多輪壓測和持續的性能優化。
首先咱們作開發的時候已經開始同步壓測。咱們進行一些功能問題修復的時候,壓測的同事能夠進行作一些單接口的壓測,找出接口性能的臨界點。開發的同事作優化的同時,壓測組模擬海量用戶在線的場景,搭建壓測的環境。
整體來說,有四輪壓測:
1)單機單接口壓測:掌握單機性能數據;
2)單機綜合壓測:定位性能損耗點,優化業務處理邏輯;
3)負載均衡壓測:評估負載均衡數量;
4)集羣全鏈路壓測:
- a. 搭建起壓機測試集羣,保證能模擬百萬量級用戶產生的數據量;
- b. 按照預估百萬量級用戶消耗的公網帶寬配置起壓機出口帶寬,真實模擬線上業務場景;
- c. 按照預估用戶量和資源消耗量對線上服務及資源集羣進行擴容,對線上服務真實壓測。
簡單總結一下,針對音畫與題目同步的實時性問題,咱們將直播流和互動通道進行對標,解決題目與音視頻之間的同步問題。
針對海量消息的實時下發問題,咱們經過將用戶分組,把大致量的消息任務化整爲零,作分佈式的分批次處理。
針對可靠性的問題,咱們經過完善快速自動斷連重試機制,以及題目消息無條件重傳,來保證弱網下的用戶也能正常參與答題活動。
另外,對於高併發問題,咱們將消息按照用戶選項進行分組,化零爲整,下降信息的推送量。同時,咱們對消息結構進行了優化,從這兩方面解決高併發問題。
最後,還有一個關鍵的核心,就是壓測,經過壓測咱們能夠快速瞭解上述解決方案是否有效,讓咱們能夠持續優化解決方案。
《實現延遲低於500毫秒的1080P實時音視頻直播的實踐分享》
《技術揭祕:支持百萬級粉絲互動的Facebook實時視頻直播》
《理論聯繫實際:實現一個簡單地基於HTML5的實時視頻直播》
《首次披露:快手是如何作到百萬觀衆同場看直播仍能秒開且不卡頓的?》
《七牛雲技術分享:使用QUIC協議實現實時視頻直播0卡頓!》
[1] 開源實時音視頻技術WebRTC的文章:
《訪談WebRTC標準之父:WebRTC的過去、如今和將來》
《良心分享:WebRTC 零基礎開發者教程(中文)[附件下載]》
《新手入門:到底什麼是WebRTC服務器,以及它是如何聯接通話的?》
《[觀點] WebRTC應該選擇H.264視頻編碼的四大理由》
《基於開源WebRTC開發實時音視頻靠譜嗎?第3方SDK有哪些?》
《開源實時音視頻技術WebRTC中RTP/RTCP數據傳輸協議的應用》
《開源實時音視頻技術WebRTC在Windows下的簡明編譯教程》
《網頁端實時音視頻技術WebRTC:看起來很美,但離生產應用還有多少坑要填?》
《了不得的WebRTC:生態日趨完善,或將實時音視頻技術白菜化》
《騰訊技術分享:微信小程序音視頻與WebRTC互通的技術思路和實踐》
>> 更多同類文章 ……
[2] 實時音視頻開發的其它精華資料:
《即時通信音視頻開發(五):認識主流視頻編碼技術H.264》
《即時通信音視頻開發(九):實時語音通信的迴音及迴音消除概述》
《即時通信音視頻開發(十):實時語音通信的迴音消除技術詳解》
《即時通信音視頻開發(十一):實時語音通信丟包補償技術詳解》
《即時通信音視頻開發(十三):實時視頻編碼H.264的特色與優點》
《即時通信音視頻開發(十五):聊聊P2P與實時音視頻的應用狀況》
《即時通信音視頻開發(十六):移動端實時音視頻開發的幾個建議》
《即時通信音視頻開發(十七):視頻編碼H.26四、VP8的前世此生》
《學習RFC3550:RTP/RTCP實時傳輸協議基礎知識》
《基於RTMP數據傳輸協議的實時流媒體技術研究(論文全文)》
《還在靠「喂喂喂」測試實時語音通話質量?本文教你科學的評測方法!》
《騰訊音視頻實驗室:使用AI黑科技實現超低碼率的高清實時視頻聊天》
《微信多媒體團隊訪談:音視頻開發的學習、微信的音視頻技術和挑戰等》
《以網遊服務端的網絡接入層設計爲例,理解實時通訊的技術挑戰》
《騰訊技術分享:微信小程序音視頻與WebRTC互通的技術思路和實踐》
>> 更多同類文章 ……
(本文同步發佈於:http://www.52im.net/thread-2022-1-1.html)