內容來源:2017年6月24日,梨享計算前端工程師謝庭在「騰訊Web前端大會 TFC 2017」進行《基於WebRTC的P2P-CND流媒體加速》演講分享。IT大咖說作為獨家視頻合作方,經主辦方和講者審閱授權發布。

閱讀字數: 4311 用時: 6分鐘

嘉賓演講視頻地址:t.cn/RBBRGfQ

PPT地址:t.cn/Rp9hZ7R

WebRTC的誕生背景

我們知道現在實時視頻通信很普遍,基於FaceTime和Skype等視頻通話工具,用戶可以很方便地與他人進行視頻對話。開發者們為了將用戶體驗優化到極致,通過大量的技術手段保障視頻質量,比如減少丟包、斷網恢復、即時響應用戶網路變化等等。實時音視頻通信對開發者的技術要求比較高,而且專利持有公司向開發者徵收授權費,並構築起巨大的技術壁壘。另一方面,對用戶來說,需要去額外安裝相應的插件或者應用程序,降低了用戶體驗,而且還有被捆綁流氓軟體的風險。這時候一種叫WebRTC的技術應運而生了。

在講WebRTC之前,我們先回顧一下Web通信的演化歷史。在AJAX出現之前,也就是05年之前,如果需要更新內容,必須重載整個網頁頁面。AJAX出現之後,通過在後臺與伺服器進行少量數據交換,AJAX 可以使網頁實現非同步更新。但AJAX不能與伺服器進行雙工通信,因此伺服器無法主動推消息給瀏覽器,只能通過瀏覽器進行輪詢。Websocket的出現使這個局面得到改觀,瀏覽器與伺服器能進行全雙工通信。不管是AJAX還是Websocket,都需要將數據發送給服務端。為了在兩個用戶間傳送數據,開發者需要購買伺服器網路,這方面的成本是非常龐大的。由谷歌支持的一項新技術——WebRTC徹底改變了這個局面。WebRTC是Web Real-Time Communication的縮寫,實現了瀏覽器之間直接的實時通訊,而不再需要伺服器中轉,谷歌致力於讓其成為HTML5的標準之一,目前大部分瀏覽器也已經支持。

WebRTC與P2P的結合

12年穀歌的chrome瀏覽器正式原生支持WebRTC,web開發者只需要幾行javascript代碼就可以開發出豐富的實時多媒體應用,而用戶也無需安裝插件,直接打開瀏覽器就可以與對方實時聊天。這時候有些嗅覺敏銳的開發者開始利用WebRTC的數據通道技術做P2P流媒體,例如國外一家公司叫做peer5。我們公司的創始人Alan在騰訊工作的時候也投入到這方面的研究,但失望的發現用WebRTC做P2P流媒體還有一些問題難以解決,比如用戶在線的時間並不穩定,當用戶關閉頁面,WebRTC的數據通道也就關閉了。隨後在13年和14年,Firefox和Opera也相繼宣佈支持WebRTC。這時Alan提出一個大膽的設想,既然瀏覽器做種不穩定,那麼把相同的協議實現在路由器和NAS中呢?我們都知道路由器是24小時開啟的,但大部分時間是處於閑置狀態,如果能把這些計算能力和網路帶寬利用起來,這樣相當於千家萬戶都是節點,你的鄰居甚至你自己也許就在為你看視頻提供加速,想想都是很酷的事情!因此我們提出了眾包CDN的概念,並且申請了專利。15年,騰訊的X5瀏覽器內核和微信也提供了支持,同年,我們梨享計算也正式宣佈成立。

可能大家會有疑問,WebRTC將來真的會成為一種主流技術嗎?我們用事實說話,看看各大瀏覽器的支持情況就知道了。從圖中可以看出,大部分瀏覽器都已支持WebRTC,包括chrome、firefox和opera,微軟的edge瀏覽器部分支持WebRTC。另外,蘋果也在近期的WWDC大會上宣佈safari11支持WebRTC。未來基於WebRTC的應用將越來越多,這是可以肯定的。

WebRTC媒體會話原理

我們假設現在有兩個瀏覽器A和B要建立WebRTC對等連接,對等連接就是兩個Web瀏覽器之間的直接媒體連接,如果A要主動聯繫B,需要先通過HTTP向信令伺服器發送一個SDP,SDP可以理解為一個電腦名片,全稱是Session Description Protocol,會話描述協議,用於描述對等連接的媒體特徵。那麼信令伺服器又是什麼呢?它就像一個紅娘,幫兩個互相不認識的人牽線。瀏覽器A發過來的SDP叫做offer,信令伺服器將其傳給瀏覽器B,後者收到後回應一個SDP對象,叫做answer,也通過信令伺服器中轉給A。交換完SDP後,兩個對等端就開始嘗試ICE打洞,打洞成功後開始協商密鑰,之後就可以開始安全的媒體或數據會話了。

ICE打洞原理

由於IPv4提供的IP資源有限,IPv6還沒有推廣開來,大部分網路設備還處於內網中,需要通過NAT設備來與外部internet連接。NAT全稱Network Address Translation,網路地址轉換,裝有NAT軟體的路由器叫做NAT路由器,它至少有一個有效的外部全球IP地址。這樣,所有使用本地地址的主機在和外界通信時,都要在NAT路由器上將其本地地址轉換成全球IP地址,才能和網際網路連接。當兩個對等端處於不同的區域網中時,需要先知道對方的公網IP和埠。這時候可以先向STUN伺服器發送測試數據包,後者做出響應,指示其在測試數據包中監測到的IP地址,此地址將成為潛在的候選地址返回。拿到候選地址的瀏覽器將其通過信令伺服器發送給對等端,對等端也進行同樣的操作,之後雙方用所有得到的候選地址嘗試連接,如果都沒有成功的情況下,會用TURN伺服器來作為中轉伺服器,TURN伺服器是在所有替代方案都無效的情況下才有採取的,因為成本比較高昂。為了加速通話建立時間,有一個叫trickle ice的方案,其思想是客戶端一邊收集candidate一邊發送給對方,比如local candidate 不需要通過stun獲取直接就可以發起,這降低了了連通性檢測完成的時間。

WebRTC數據通道

接下來介紹一個比較重要的概念——WebRTC data channel。我們基於WebRTC來做P2P流媒體,實際上就是用的data channel能力。那麼data channel到底是什麼呢?雖然有關WebRTC的宣傳主要側重於它對於實時音視頻通訊的支持,但設計師一直都希望它也支持實時數據傳輸。相比Websocket和HTTP,數據通道支持流量大、延遲低的連接,具有穩定可靠等優點。而且data channel的介面和websocket一樣,也是通過send來發送數據,通過ommessage來接收數據。那麼如何對data channel數據傳輸的可靠性進行控制呢?通過剛才所講的dataChannelOptions這個javascript對象,可以讓data channel在UDP或者TCP的優勢之間進行切換,比如讓數據傳輸得更加穩定可靠,或者傳輸得更快。其中有幾個比較重要的欄位:ordered:設置數據的接受是否需要按照發送時的順序,maxRetransmitTime:設置數據發送失敗時,多久重新發送,maxRetransmits:設置數據發送失敗時,最多重發次數。主要是配置ordered,當設置為true時數據通道表現更像TCP,false時表現更像UDP。

梨享計算與WebRTC

此外,我們公司一直對WebRTC標準化保持著關注並貢獻力量。在去年,我們在研發過程中發現有一個第三方的webrtc協議棧能與chrome瀏覽器進行通訊,但無法與firefox通訊,通過對比SDP發現firefox有一處實現與標準規範不一致。於是我們與firefox開發團隊取得聯繫,提交了我們的修改建議,最初他們認為沒有問題,但最終還是採納了我們的建議,對sdp進行了修改。這也算是我們對推進webrtc標準化做出的一點點貢獻。另外,我們也一直與騰訊瀏覽器內核團隊保持著聯繫,爭取WebRTC技術以及本次分享的上層的P2P-CDN加速協議得到全面的支持。

WebRTC與P2P流媒體

把WebRTC的data channel搞清楚後,我們就可以用用它來做P2P流媒體了。這方面已經有國外大神開發的知名開源項目:WebTorrent,在github上有1萬多顆星。WebTorrent是一個開源的基於WebRTC 和BT協議的js框架,完全用javascript編寫,可以同時運行於 Node.js 和瀏覽器,由於基於WebRTC,因此WebTorrent不需要安裝任何插件,就可以跑在瀏覽器上。同時支持Chrome, Firefox 和 Opera瀏覽器。但是由於是基於BT協議,所以是一種pull-based的演算法,這種演算法是一種隨機抓取的策略,隨機抓取其它節點的buffer,但這樣會存在一個問題:抓取的buffer不一定是目前需要的,也不一定是其他節點需要的,而且還會浪費下行帶寬和其它節點的上行帶寬,因此同時造成了「帶寬飢餓」和「內容飢餓」問題。下面介紹一種改進版的pull-based演算法——FirstAid演算法。FirstAid是基於窗口滑動的,每隔一段時間觸發一次窗口滑動,每個窗口又可以分成三段:urgent、normal和prefetch,urgent顧名思義,是離播放時間最近的buffer,所以優先順序別最高,normal和prefetch優先順序遞減。當父節點為子節點傳輸buffer時,會優先滿足urgent級別的要求,而暫停normal級別的,所以最緊迫的需求會優先得到滿足,當子節點的urgent需求得到滿足後,需要回過頭來彌補他的競爭對手的需求,以達到一種互惠互利的狀態。和剛才pull-based演算法思想截然相反的是push-based演算法,其中比較有代表性的是FashMesh演算法,由港科大的學者提出來的一種P2P演算法。FashMesh是基於一種叫Streaming Mesh的演算法,將源節點的數據流分成多個子流,通過多棵生成樹構成mesh來源源不斷的傳輸給子節點,這種演算法的優勢是延遲低,帶寬利用率高。Fast Mesh還可以根據每個子節點的上行帶寬來動態的調整網路拓撲結構,讓上行帶寬大的節點更加接近源節點,從而充分利用網路的現有能力。根據一項對比試驗,FastMesh可能是目前眾多P2P演算法中效果最好的。但這個演算法也有缺點,當節點進入或離開網路時,都需要重新調整拓撲結構,因此不適合節點變化較大的情況。

我們自行研發的演算法——Push-Pull演算法則綜合了push-based和pull-based兩種演算法的優勢,用pull的方式從父節點獲取優先順序最高的buffer,由父節點以push的方式為其提供後續的buffer。另外,我們的演算法混合HTTP、HTTPS、WebRTC、Websocket等多種協議,在優先保證用戶體驗的前提下最大化P2P率。經過測試,Push-Pull演算法具備低延遲、高帶寬利用率、高P2P率、對網路拓撲結構變化魯棒性強等優勢。

PearPlayer

PearPlayer(梨享播放器,github地址:github.com/PearInc/Pear) 是完全用JavaScript寫的開源HTML5流媒體播放框架,實現了融合HTTP(包含HTTPS、HTTP2)、WebRTC的多協議、多源、低延遲、高帶寬利用率的無插件Web端流媒體加速能力。基於H5的MSE技術(Media Source Extension)將來自多個源節點的Buffer分塊餵給播放器,再加上精心設計的演算法來達到最優的調度策略及對各種異常情況的處理,Pear Player能在保證用戶流暢視頻體驗的前提下最大化P2P率。

集成我們的PearPlayer.js也非常簡單,只需要短短几行代碼,把我們的js文件引入到script標籤中,並把video的id還有token作為參數傳給我們提供的函數中即可。Demo演示地址:qq.webrtc.win/watch,以下是demo截圖。

除了播放器外,我們還開發了支持多協議、多源、混合P2P-CDN的下載器PearDownloader,可用於高清圖、壓縮包、軟體發布或升級包、音樂、文檔等大文件下載或在線服務的場景(github地址:github.com/PearInc/Pea…),Demo演示地址:qq.webrtc.win/download。

霧計算

最後,講一下霧計算有關的內容。霧計算與雲計算有什麼區別呢?雲在天空飄浮,高高在上,遙不可及;數據中心距離終端用戶較遠,用戶消息需要經過若干跳纔能夠到達。而霧是貼近地面的雲,是現實可及,就在你我身邊。霧計算並非由性能強大的伺服器組成,而是由性能較弱、更為分散但離用戶更近的各類計算設備組成,例如智能路由器、網路存儲設備等。霧能夠彌補雲的不足,並和雲相互配合,協同工作。我們Pear公司一直在踐行霧計算的理念,通過與國內知名的路由器、NAS廠商合作,我們擁有海量可持續穩定提供服務的節點。大部分帶寬、存儲、計算資源通過眾包方式收集自終端用戶穩定在線的邊緣設備,服務能力覆蓋全部地域、所有運營商、每處網路邊緣。我們自研的調度系統可以動態、實時的感知和調度,讓數據傳輸距離儘可能接近「零跳」。

相對於傳統的模式,我們可以說是站在共享經濟的風口上。我們知道傳統的CDN廠商會先以批發價從ISP買進帶寬,然後再以零售價賣給CP,CP買入帶寬後進行內容分發,為終端用戶提供CDN服務。我們與硬體廠商合作,在其設備中植入我們的軟體,從而在千家萬戶擁有了分佈廣泛的節點。CP廠商和傳統CDN廠商從我們這裡買入帶寬,我們將其內容分發到各個節點中,持有設備的用戶在提高其計算資源和帶寬資源的同時,也會得到我們的返利,BGP機房、ISP骨幹網的壓力也得以緩解,從而實現多贏局面。


推薦閱讀:
相關文章