1. 程式人生 > >基於Licode的WebRTC全球分散式架構

基於Licode的WebRTC全球分散式架構

640?wx_fmt=jpeg


隨著線上教育行業的興起, 許多人把目光投向了國外市場,而如何搭建全球化的音視訊網路就成為了其中的關鍵問題。百家雲研發工程師陳聰詳細介紹瞭如何利用Licode 開源伺服器搭建全球分散式架構以解決常見的教育場景的問題。本文來自陳聰在LiveVideoStackCon 2018上的演講,由LiveVideoStack整理而成。


文 / 陳聰

整理 / LiveVideoStack


大家好,我是來自百家雲的陳聰,今天我將為大家帶來與Licode的WebRTC全球分散式架構相關的技術分享。之所以想為大家介紹這個架構,是因為我在使用WebRTC開源伺服器時發現WebRTC並沒有提供類似於分散式或叢集的整體解決方案,希望百家雲在此領域的探索能為大家帶來有價值的幫助。


1. SFU


1.1 SFU簡介


640?wx_fmt=jpeg


SFU全稱為Selective Forwarding Unit,我們可以將其原理簡單理解為將一條流推給多個端並且在整個過程中不對視訊進行編解碼處理。相對於其他傳統的需要重新編解碼的解決方案而言,其優點在於低延遲、低消耗。當然,單SFU的缺點也顯而易見。


1.2 單SFU問題


1)人數限制


640?wx_fmt=jpeg


單SFU面臨的第一個問題是人數限制,主要出現在像“雙師課堂”這種較為常見的教育場景中。在此場景中,一位老師為多名學生教學,多名學生接收由老師端傳送的流。有時在“雙師課堂”中容易出現老師端位元速率較高的情況,以1080p、30FPS的情形為例,此時一位學生所需頻寬為3.5MB;如果有兩百位學生線上觀看則單個伺服器的出口頻寬就會達到700MB左右,並且隨著學生人數的增加,所需出口頻寬越來越多;而單個SFU的頻寬是有限制的,如我們常用的阿里雲、騰訊雲的頻寬在300~500MB左右。由於單個伺服器的頻寬限制,單節課同時線上人數便無法達到一個較為理想的規模。


2)地理分佈,就近接入

 

640?wx_fmt=jpeg


地理分佈與就近接入是我們在探索單SFU中面臨的第二大問題,此問題主要出現在“小班課”的教育場景。雖然與“雙師課堂”相比“小班課”在人數上沒有那麼大的規模,一般情況下一節課線上人數為6~15人,但由於在此場景中老師與學生的地理跨度較大,也許分佈在世界各地。這就使得我們必須選擇質量高擴充套件廣的伺服器作為接入點。可由於單SFU的原因,我們只能選用相對於所有使用者較好的伺服器,如上圖我們選用上海的伺服器。但這也導致距離伺服器較遠位置的使用者相對於伺服器所在地的使用者其感受到的延遲更為明顯。

 

640?wx_fmt=jpeg


如果將使用者拓展到全球範圍來看的話,那麼由其造成的延遲問題就更為明顯。如上圖情況,學生在中國而老師在美國的話,學生看老師就會增加2倍的跨洲延遲。同時,高延遲除了造成視訊的卡頓、丟包,還會造成流量的浪費。如果不解決這些問題,我們便無法部署一個性能優異的全球化分散式網路架構,那麼如何解決這些問題呢?


2. 解決方案:級聯SFU

 

640?wx_fmt=jpeg


我們的思路是通過級聯SFU而非單SFU解決上述問題,也就是將SFU相互級聯後,使客戶端釋出的流經過另一個SFU轉發,其它客戶端再從另一個SFU訂閱。


2.1 解決人數限制

 

640?wx_fmt=jpeg


級聯SFU解決的第一項問題是人數限制,受單伺服器的出口頻寬所限,如果線上人數達到一定規模那麼學生就無法成功訂閱來自老師的視訊。此時如果通過級聯SFU把來自老師端的流通過下一層伺服器進行轉發和路由,不僅可解決人數限制的問題,還可增加動態擴充套件的功能,也就是根據新加入學生的人數動態擴建伺服器,從而實現節省資源的目的。


2.2 解決地理分佈與就近接入問題

 

640?wx_fmt=jpeg


單伺服器造成的跨地域使用者延遲問題,可通過級聯伺服器解決。通過對每位使用者的IP進行解析,系統就可獲知此使用者所在地理位置並根據地理位置資訊為使用者就近分配可用伺服器節點,從而儘可能降低由於地理跨度帶來的視訊延遲。

 

640?wx_fmt=jpeg


而對於全球化來部署來說,由於一個洲所擁有的一般為一整個伺服器叢集,有可能此伺服器叢集下有多個SFU進行多層級聯,這就便於我們搭建起一個簡單的全球化分散式網路架構。


3. Licode介紹

 

640?wx_fmt=jpeg


接下來我將為大家介紹Licode,上圖展示的是部分Licode官方介紹。Licode相當於一個部分基於WebRTC原始碼但完全相容WebRTC的開源SFU伺服器,具有簡單可用易伸縮的優點,也支援視訊會議,推流和錄製等功能。

 

640?wx_fmt=jpeg


從底層到上層,我們來看一下Licode的各個模組。最底層的Erizo模組實現WebRTC的基本協議如(ICE,SDP,DTLS等),實現WebRTC協議棧後Licode就可和瀏覽器進行通訊並把瀏覽器的視訊流上傳至伺服器;再上一層是ErizoAPI,相當於一層封裝,通過NodeJS的封裝層封裝C++使得上層可通過NodeJS呼叫相應模組;ErizoAPI上一層是Erizo Controller,這部分通過JS實現的程式碼相當於封裝下一層的呼叫,開發者可通過JS對其進行快速開發並實現特殊邏輯如房間邏輯、釋出者邏輯、訂閱者邏輯等或實現類似於(Token)驗證等功能;最頂層的Nuve則主要用於通過API呼叫多項功能如API建立房間,API管理使用者等等。

 

640?wx_fmt=jpeg


上圖展示的是Licode模組的整體架構。由上至下,第一層的CustomServerApp通過建立的Port3000呼叫Nuve API,而資料則通過MogonDB儲存;第二層的RabbitMQ會處理相應的信令並分散式;圖中紅框標示的部分是ErizoJS與WebRTC,此部分程式碼使用JS進行封裝,這個模組主要封裝了釋出者、訂閱者等邏輯。開發者可通過這裡的程式碼直接建立一個釋出者或訂閱者從而實現與前端瀏覽器之間的通訊。


4. 基於Licode級聯實現

 

640?wx_fmt=jpeg


百家雲將Licode ErizoJS 模組單獨提取並使其直接與信令通訊,這裡給大家詳細描述一下流程。信令會和ErizoJS與客戶端連線,信令會根據客戶端的ip,給客戶端選擇就近的ErizoJS,同時將視訊流釋出至此伺服器上;假若此時有一位於上海的客戶端接入而視訊流來自北京,那麼信令就可偵測到二者不在同一區域,就會把北京的視訊流推至上海的ErizoJS;與此同時,我們也會在上海的伺服器端建立一個Router,此Router同樣也是Publisher,上海的客戶就可以使用這個Publisher 建立一個 Subscriber 來訂閱視訊。 


4.1單節點Docker化

 

640?wx_fmt=jpeg


除了實現Licode級聯,百家雲也對Licode部分程式碼進行了優化,首先是單節點Docker化。這裡的ErizoJS相當於一個SFU伺服器,我們所做的就是將此模組Docker化從而組成一個新的模組,此Docker化的模組可實現動態擴充套件、快速部署等功能。由於教育場景下,在某些時間段,如工作日晚6點至9點或週末部分時段出現流量與視訊流的高並發現象,同樣在凌晨時段訪問量較少,一直開著一定數量的伺服器並不是經濟實惠的選擇。Docker化之後根據需求動態調動部署伺服器,既達到動態擴容的效果又節省了流量和開銷,可謂兩全其美。


4.2級聯間去加密

 

640?wx_fmt=jpeg


百家雲在細節上的優化也值得分享,比如說級聯之間去加密。大家應該知道WebRTC本身是基於加密傳輸,其會實現一層DTLS SRTP加密,而此加密對於伺服器和伺服器直接傳輸來說是不必要的,因此我們取消了這一層程式碼並重新實現了Licode::Transpore類,實現ICE傳輸。因為DTLS SRTP加密之前本身會有一個(握手)過程,如果我們去掉此加密層就會加快連線速度,同時也節省了加密計算的資源。


4.3其他級聯優化

 

640?wx_fmt=jpeg


其他的一些優化如ICE也必不可少。因為Licode基於Libnice開發,而Libnice本身存在一個全域性鎖問題。我們在開發的過程中發現當併發或流量達到一定高度時就會出現嚴重的丟包阻塞問題。我們的解決方案相是自己重新實現ICE並替換原來的Libnice資料包。除了ICE,我們還進行了Simulcast、FEC、NACK等優化。由於Licode本身是客戶端與伺服器之間的通訊,並沒有實現伺服器與伺服器之間的功能。我們在此基礎上進行優化從而實現了伺服器與伺服器之間的傳輸。


4.4全球化

 

640?wx_fmt=jpeg


最後我想為大家簡單介紹一下教育場景全球化部署例項。我們主要針對三個區域進行全球化部署:東南亞、美國與歐洲。為了保障東南亞國家如菲律賓等的接入穩定,會選擇從香港或新加坡接入,有時出於優化網路的目的還需拉專線或通過就近運營商接入優;而對於美國,由於其網路質量相對於東南亞國家更好,與中國連線的線路相對於中歐或東南亞的條件更好,所以不需要花費太多時間進行優化;中東歐國家一般通過國內常用的位於法蘭克福的節點進行傳輸,再通過愛爾蘭、英國等國家與地區接入從而儘可能優化網路質量。


精品文章推薦




技術乾貨: