作者:忘籬
來源:
SRS 開源伺服器
從哪裡開始
我們看最簡單的視訊服務,推一個流,隻有一個播放器消費流,我們隻需要一個 SRS Origin 源站服務就可以:
listen 1935;
max_connections 1000;
vhost __defaultVhost__ {
}
Remark:SRS 啟動時預設就是 Origin 源站模式。
假設我們把 SRS 源站部署在杭州阿裡雲的 ECS 上,主播使用 OBS 在上海推流,觀衆在北京觀看,如下圖所示:
Remark:雖然地域較遠,但 ECS 是 BGP 帶寬,效果其實不錯的。
Remark:雖然隻有一台伺服器,SRS 能支援 3K 個推流流,或者 7.5K 個播放,詳細參考 SRS 的性能報告。
Note:可能你實測的資料不同,以上資料是在特定環境的結果,包括:流的碼率,伺服器 CPU 主頻和帶寬能力,選擇的協定,SRS 的版本等差異影響。
如何支援更多的播放
不管是移動端 Native 播放的 RTMP/FLV,還是移動端浏覽器播放的 HLS,或者 WebRTC 播放器,所有的視訊服務最終是有播放的,在會議中叫訂閱或與會者,本質上就是消費視訊流。
在直播場景中,一個流會被非常多的播放器消費,比如一個球賽、國慶活動、一個電商大 V 的直播,直播對于播放的擴充能力是核心訴求,這也是 CDN 解決的關鍵問題之一,當然我們使用 SRS 也可以建構這樣的能力,差別在于 CDN 的帶寬成本會更低,而 SRS 一般部署在 BGP 雲機房,網絡穩定性更高但成本更高。
在會議或線上教育中,一個流可能不會被那麼多人消費,比如一個 100 人的會議,可能一個視訊流隻會被另外 99 個人消費,如果在 MCU 模式下這些流會被合并後被其他與會者消費,如果開啟語音激勵或者使用者選擇,可能隻有說話的人會被其他人消費,本質上和直播的連麥很像,在視訊服務中大部分是不對等的情況,推流的少播放的多或者多太多。
在監控或者一對一聊天場景中,一個流會被少量的播放器消費,一對一就是一個播放器消費,監控可能更特殊些可能沒有人消費隻有在某些時候才會被消費,比如 GB28181 使用 SIP 協定,在有播放器消費流時才邀請攝像頭把流送上來。
SRS 支援 Edge 邊緣伺服器,來擴充源站的支援播放的能力。我們将源站部署在阿裡雲杭州 ECS 上,主播從上海使用 OBS 推流,杭州我們需要支援 4K 播放,北京我們需要支援 8K 播放,我們就可以在杭州和北京部署 SRS 邊緣伺服器,如下圖所示:
Remark:播放器如何找到對應的SRS邊緣伺服器,可以新增一個排程伺服器,播放器請求排程伺服器的HTTP API,排程傳回邊緣伺服器的IP就可以。
Remark:排程服務也可使用DNS服務,現在雲廠商一般也提供DNS服務,可以根據播放所在的區域,解析到對應的IP上。
這個結構是可以水準擴充的,一個 SRS 源站,最多可以支援 7K 個邊緣節點。如果 7K 個節點不夠,還可以使用多級邊緣伺服器,完成無數個節點的擴充能力。
SRS 如何用多個 CPU
SRS 使用單程序單線程模型,可以避免線程切換的消耗,也可以避免并發和競争條件,是以預設情況下 SRS 隻能使用一個 CPU,也就是雖然機器有 4 個 CPU 最高能跑到 400%,但 SRS 隻能用一個 CPU 最高隻能跑 100%。
當然這是預設情況,是有解法的:
- 降低機器的 CPU 個數,比如申請 ECS 時隻申請 2 個 CPU 的,這樣就不會有多個 CPU 的煩惱了。
- 使用 K8S 和 Docker 虛拟化資源,使用 Docker 跑 SRS,這樣每個 SRS 最多用 100%,但可以跑多個 Docker。
- 使用 SRS 的多程序和叢集方案,如果确實需要使用多 CPU 能力,還是會有方案的,下面詳細講這種。
我們先考慮單個源站伺服器如何使用多程序,比如 4CPU,單個 SRS 隻能支援 7K 播放,我們可以擴充 4 倍能力到 28K 播放。單程序的部署結構如下:
源站的多程序部署結構如下:
Remark:這種部署結構隻能擴充源站的播放能力,因為新增的是 Edge 伺服器,流最終還是要回源到 Origin 伺服器。
當然這種結構如果将源站單獨部署到一台伺服器後,就變成了上一章所講的結構了,差異在于上一章的每個 Edge 伺服器還是單程序,沒有使用 Reuse Port 擴充多程序能力,這兩個結構是可以結合起來用的,如下圖所示:
Remark:在這個結構中,每個Edge伺服器上也部署了多個SRS Edge程序,這樣可以将邊緣伺服器的多核能力用起來。
到目前為止,我們更多關注的是播放的擴充能力,如何擴充推流能力呢?下面開始講這個。
如何收更多的流
推流能力,一般也叫收流的能力,因為推流就是指用戶端将流推送到 SRS,而從 SRS 角度看就是把用戶端的流收了提供服務。
在 SRS 的角色中,Edge 主要解決播放或下行的擴充能力,而 Origin 則是解決上行或推流的擴充能力。
Origin 源站提供了多個方案來實作擴充,按照上面的場景,我們假設杭州有 3K 的主播,為了業務穩定性我們不能部署一個 Origin 伺服器來支援 3K,這會導緻 CPU 跑得比較高,而且一般源站還需要錄制或轉 HLS,需要預留一些 CPU 出來做其他業務。
SRS 支援 Vhost,可以将流分成不同的邏輯域,比如 3K 個流,我們可以分成 2 個 Vhost,這樣每個 Vhost 的流隻有 1.5K,可以推流到 2 個源站,如下圖所示:
Remark:我們用兩個顔色區分了兩個 Vhost,對于 Edge 來說不同的 Vhost 可以回源到不同的 Origin,是以可以從同一個 Edge 播放不同的 Vhost 的流。
Note:圖中播放器連接配接的是 Edge 伺服器,實際上推流也可以推到邊緣的,沒有必要必須推源站。
Note:建議用戶端連接配接 Edge,而不直接連接配接 Origin,這樣可以獲得更好的一緻性,比如播放時隻需要加 Query 參數指定 vhost 就可以,而不用關心 Origin 會根據不同 Vhost 有不同的位址。
Note:Vhost 的優勢是完全獨立的源站,不會互相幹擾,在用戶端指定了 vhost,相當于在用戶端做了負載均衡,系統結構比較簡單,劣勢是業務是有感覺的。
如果業務不按照 Vhost 區分,或者一個 Vhost 的流也非常多,那麼 SRS 提供了 Origin Cluster 源站叢集擴充源站,如下圖所示:
Remark:兩個 Origin 伺服器之間會互相查詢流,若 Edge 請求的流不在本源站上,會将 Edge 定向到有流的 Origin,詳細請參考 OriginCluster 的 WIKI 說明。
Note:同樣的,建議不要直接推流到 Origin,而推流到 Edge。
Note:源站叢集優勢是部署時比較簡單,不需要根據業務配置 Vhost,劣勢是源站之間是需要互相通路的。
值得說明的是,由于源站是流的最終所在地,是以他本質上是有狀态的,兩個源站并不是完全等價的。而邊緣可以認為是合并回源的代理,兩個 Edge 是沒有差别的,它們并沒有存儲流的資訊,都是通過源站擷取流。是以,推流的擴充能力,比播放的擴充能力,對系統的挑戰是更大的。
在監控領域,可能有 10 萬或 100 萬攝像頭,如果需要把這些攝像頭的流全部推送到伺服器處理,那這個量級還是非常的大的。一般會在本地處理後,再把流送到伺服器,比如圖像識别到攝像頭有活動,可以把資訊送到伺服器,需要觀看這個流後,再把流送到伺服器。
不建議的做法
發現還是會有少對 SRS 的誤用,這裡列出來一些不建議的做法:
- 不建議 Forward,Forward 并不是擴充叢集的能力,而是把流複制一份給别的系統,一般在系統遷移,或者需要兩個系統有同樣的流時,才需要用 Forward。
- 不建議在邊緣切 HLS 和 DVR,因為邊緣沒有流,是以無法切片 HLS,隻能在有播放 RTMP 或 FLV 時,才會去把流拉到邊緣。是以如果邊緣做 HLS 切片,會發現播放 HLS 前要播放 RTMP,這是很奇怪的做法。
- 不建議把所有業務放一台伺服器,比如有些流是指需要出 HLS,有些流隻需要 DVR,有些流隻需要 FLV,那麼這些流就應該分成不同的 Vhost,送到不同的源站處理,這樣可以避免互相幹擾。比如 HLS 和 DVR 需要寫磁盤,可能會導緻 IO 負載高,可能會影響到 FLV 流。
- 不建議把業務做到 SRS 中,比如無人播放時停止推流,那麼不應該讓 SRS 斷開連接配接,而應該業務系統觀察到無人播放時,通知推流停止推流。這樣可以讓 SRS 集中在流媒體處理,而不是因為業務代碼 Crash。
- 不建議 Edge 前面挂 F5 或 Proxy,Edge 本身就是 Proxy,再挂個 Proxy 意欲何為呢,流量一點都沒有節省。有些可能是為了讓用戶端通路的 IP 保持一緻,那麼可以用 DNS 域名方式,這樣用戶端看到的都是一個 DNS 名稱,會解析成不同的 Edge 的 IP。
還有些值得特别說明的:
- 以上擴充能力,可以組合使用,比如源站可以是單個 SRS,也可以用一個 Origin 和多個 Edge 組成小叢集源站,再讓 Edge 使用 Reuse Port 對外就是一個 IP 和端口。
- Edge 拉流可以支援多個協定,對于擴充同樣是适用的,比如 WebRTC 也可以使用 Edge 擴充播放的能力,同樣 GB28181 推流後播放的協定和源站架構無關。但目前 WebRTC 推流和源站叢集的能力還在開發中。
- 一般來說,Edge 就是為了擴充播放的能力,但推流也可以走 Edge 這是為了讓推流的位址更簡單,而不用關注 Origin 的部署結構。一般來說,源站 Origin 是為了擴充收流的能力,但對于 WebRTC 這種結構,可能沒有固定的 Origin 和 Edge,它可能需要的是一種切換角色的能力。
「視訊雲技術」你最值得關注的音視訊技術公衆号,每周推送來自阿裡雲一線的實踐技術文章,在這裡與音視訊領域一流工程師交流切磋。