Shou.TV 背后基于 Node.js 和 WebSocket 的技術架構
我們使用一個定制的基于WebSocket的協議SLSP來實現廣播和直播。所有組件均由Nginx代理,部署于Ubuntu server上。組件間通過HTTP和JSON通訊。
Shou.TV 背后基于 Node.js 和 WebSocket 的技術架構
技術
在Shou.TV,我們有如下幾條“軍規”。我們盡最大努力,在日常開發中堅守這些規定。
-
在造輪子之前先選用已有解決方案中最好的那一個。工程師們都熱愛自行造輪子。但是為了交付產品,我們需要快速地構建,并確保產品的穩定性。
-
掌握核心技術。如果在我們的核心架構中引入第三方解決方案,我們應當盡最大的努力去理解各個方面。如果我們能力不足以理解該解決方案,或者該解決方案并不值得我們花時間去搞懂,那么就構建我們自己的解決方案。
-
不要將核心技術綁定在一家供應商上。我們應當確保解決方案可以被移植到任何服務器上。
-
盡可能快地完成非核心技術。使用任何一個可用的軟件或解決方案。以后有時間的時候在去理解它。
根據這些規定,我們在Shou.TV使用下列技術。
-
從不同的供應商處租用VPS,例如EC2、GCE、Linode、Rackspace、DigitalOcean等等。
-
使用Ubuntu 14.04 LTS。它擁有最新的軟件,并不像CentOS那樣保守。
-
對網站、API、聊天室和廣播服務器的所有請求,都經由Nginx,并開啟SSL。
-
使用MongoDB作為主數據庫。
-
使用Ruby on Rails開發網站和API服務器。
-
使用Socket.IO和Redis開發聊天室。
-
使用Node.js和FFmpeg開發了基于WebSocket的自定義廣播協議——SLSP。
-
使用HLS支撐視頻直播和視頻回放。使用Video.js作為web播放器和Android視頻播放器。
-
使用Google云存儲來存檔視頻片段。
-
使用Amazon S3存儲小資源,例如用戶頭像。
-
使用Git管理代碼。使用Capistrano部署。
網站和API
我們使用最新的Ruby on Rails和Unicorn來開發網站和客戶端API。所有請求都經由Nginx和SSL代理。我們使用越來越多的memcached來應對持續增長的用戶。數據庫是一個MongoDB的集群。
我們還沒有遇到大量的訪問。所以在用戶大量涌入時,我們無法確保可用性。但是我們已經設計了基于AWS Route 53和Elastic Load Balancing或者GCE Network Load Balancing的整套負載均衡架構。
聊天室
聊天室是一個平衡負載后簡單的Socket.IO服務器集群,它使用redis集群分發郵件和聊天室,使用相同的cookie和會話進行用戶認證的主要網站。
網絡聊天界面是使用Socket.IO的客戶端庫,iScroll.js和簡單的jsrender模板庫。
我們使用AndroidAsync圖書館建立Android的聊天室,有幾個問題,我們已經做了一些補丁。
廣播服務器
我們定義了一個基于WebSocket的自定義直播流媒體協議:SLSP,并只用了大約1000行Node.js和C語言代碼實現。
原因是,RTMP非常舊,而且難于理解及使用大型、可用的HTTP解決方案,相比WebSocket或SLSP而言,它只是個“穩定”的騙局。我在多媒體開發領域有幾年經驗,但在Wowza或任何當前可用的RTMP服務器上,修復這類問題或實現自定義特性仍然感覺困難。
網絡正快速革新,對所有人來講,HTTP是一個更成熟、更容易理解的協議。我們有很多高性能的開源HTTP服務器,比如:nginx,具有非常高的性能且保持高穩定性。
WebSocket是一個長連接協議,適用于視頻流。所有現代瀏覽器都支持WebSocket。WebSocket內置SSL,故而客戶端和服務器端都不需要任何附加代碼。WebSocket使用和HTTPS一樣的443端口,因為可以穿越絕大多數防火墻。
SLSP,簡而言之,如同一個WebSocket聊天室。只需要將服務器部署在Nginx代理之后,一旦WebSocket客戶端向服務器發送持續的視頻流,SLSP就會將視頻流分段成數個HLS TS段,故而任何一個可用的HLS播放器都可以播放視頻流了!
WebSocket可以使用大量可用的高性能HTTP解決方案。SLSP是基于WebSocket的,理所當然我們也可以構建非常健壯的智能負載均 衡方案。如上圖所示,無論何時我們啟動一臺新的SLSP服務器,它都會向負載均衡器注冊自身。每一個SLSP服務器都會持續地向均衡器發送自身的狀態,例 如服務器當前負載。
當一個SLSP客戶端想要去廣播, 它首先要向負載均衡器請求一個SLSP服務器的地址,均衡器會基于潛在的服務器負載,選擇一個最合適的SLSP服務器,然后客戶端會直接發布視頻流到SLSP服務器。
無論什么時候負載均衡器遇到高負載,它都會在幾分鐘內自動建立一個新的SLSP服務器, 并且我們還會進一步改進它。均衡器會移除空閑的SLSP服務器以節省開銷。
廣播結束之后,為了將來可以回放,服務器將會上傳完整的流到Google云。
去更新吧
Shou.TV 仍然是一個很新的項目,它的用戶不多,因此我們還沒有驗證在高負載下的情形。我們將會持續改進和發布更多細節。