網上有很多關于雙流區個人如何申請pos機,流媒體服務器如何實現負載均衡的知識,也有很多人為大家解答關于雙流區個人如何申請pos機的問題,今天pos機之家(www.tonybus.com)為大家整理了關于這方面的知識,讓我們一起來看下吧!
本文目錄一覽:
雙流區個人如何申請pos機
作者:Winlin、Azusachino、Benjamin
編輯:Alex
▲掃描圖中二維碼或點擊閱讀原文▲
了解音視頻技術大會更多信息
當我們的業務超過單臺流媒體服務器的承受能力,就會遇到負載均衡問題,一般我們會在集群中提供這種能力,但實際上集群并非是唯一的實現方式。有時候負載均衡還會和服務發現等時髦詞匯聯系起來,而云服務的LoadBalancer無疑不可回避,因此,這個問題其實相當復雜,以至于大家會在多個場合詢問這個問題,我打算系統地闡述這個問題。
如果你已經知道了以下問題的所有答案,并且深刻了解背后的原因,那么你可以不用看這篇文章了:
? SRS是否需要Nginx、F5或HAProxy做流代理?不需要,完全不需要,這樣是完全誤解了流媒體的負載均衡。而HTTPS我們卻建議這么做,同時為了減少對外服務的IP又建議用云LoadBalancer。? 如何發現SRS邊緣節點?如何發現源站節點?對于邊緣,通常DNS和HTTP-DNS都可以;而源站是不應該直接暴露給客戶端直接連接的。? WebRTC在服務發現上有什么區別?由于CPU性能損耗更大,負載均衡的閾值更低;在單PeerConnectIOn時流會動態變化,導致更難負載均衡;移動端UDP的切網和IP漂移,會引入更多問題。? DNS和HTTP-DNS哪個更合適作為流媒體服務器的服務發現機制?肯定是HTTP-DNS,因為流媒體服務器的負載變化,比Web服務器的變化更大,考慮新增1K的客戶端對于兩種不同服務器的負載影響。? 負載均衡是否只需要考慮如何降低系統負載?首要目標是考慮降低系統負載,或者防止系統過載導致質量問題甚至崩潰;同時在同等負載時,也需要考慮就近服務和成本因素。? 負載均衡是否只能靠增加一層服務器?一般大型的CDN分發系統,明顯是分層的,無論是靜態的樹設計,還是動態的MESH設計,在流的傳輸上都是靠分層增加負載能力;同時,還能通過端口重用(REUSEPORT)方式,用多進程方式增加節點的負載而不會增加層。? 負載均衡是否只能使用集群方式實現?集群是基本的增加系統容量的方式,除此之外,也可以通過業務分離配合Vhost實現系統隔離,或者通過一致性hash來分流業務和用戶。好吧,讓我們詳細聊聊負載和負載均衡。
What is Load?在解決系統均衡問題時,首先我們看看什么是負載?對于服務器來說,負載就是因為有客戶端的訪問,而導致的資源消耗上升。當資源消耗出現嚴重不均衡,可能會導致服務不可用,比如CPU跑滿了,所有客戶端都會變得不正常。
對于流媒體服務器而言,就是流媒體客戶端導致的服務器資源消耗。一般我們會從服務器資源消耗角度度量系統負載:
? CPU:服務器消耗的CPU,一般我們稱CPU消耗較多的為計算密集型場景,而把網絡帶寬消耗較多的稱為IO密集型場景。直播場景一般屬于IO密集型場景,CPU一般不會首先成為瓶頸;而在RTC中卻不是,RTC是IO和計算都很密集,這是非常大的差異。? 網絡帶寬:傳輸流媒體時需要消耗網絡帶寬,也就是上文介紹的IO密集型場景。流媒體肯定是IO密集型場景,所以帶寬一定是重要的瓶頸。而有些場景比如RTC同時還是計算密集場景。? 磁盤:如果不需要錄制和支持HLS,那么磁盤就不是重要的瓶頸,如果一定開啟錄制和HLS,那么磁盤將變得非常關鍵,因為磁盤是最慢的。當然由于現在內存較多,所以一般我們采用掛內存盤的方式避免這個問題。? 內存: 相對而言,內存是流媒體服務器中消耗較少的資源,盡管做了不少Cache,但是內存一般還是不會首先達到瓶頸。所以一般內存也會在流媒體服務器中大量用作Cache,來交換其他的資源負載,比如SRS在直播CPU優化時,用writev緩存和發送大量數據,就是用高內存換得CPU降低的策略。當負載過高,會有什么問題?負載過高會導致系統直接出現問題,比如延遲增大,卡頓,甚至不可用。而這些負載的過載,一般都會有連鎖反應。比如:
? CPU: CPU過高會引起連鎖反應,這時候意味著系統無法支持這么多客戶端,那么會導致隊列堆積,從而引起內存大量消耗;同時網絡吞吐也跟不上,因為客戶端無法收到自己需要的數據,出現延遲增大和卡頓;這些問題反而引起CPU更高,直到系統崩潰。? 網絡帶寬: 若超過系統的限定帶寬,比如網卡的限制,或者系統隊列的限制,那么會導致所有用戶都拿不到自己需要的數據,出現卡頓現象。另外也會引起隊列增大,而處理堆積隊列,一般需要消耗CPU,所以也會導致CPU上升。? 磁盤: 若超過磁盤負載,可能會導致寫入操作掛起。而在同步寫入的服務器,會導致流無法正常傳輸,日志堆積。在異步寫入的服務器,會導致異步隊列堆積。注意目前SRS是同步寫入,正在進行多線程異步寫入。? 內存: 超過內存會OOM,直接干掉服務器進程。一般內存主要是泄露導致的緩慢上漲,特別是在流很多時,SRS為了簡化問題,沒有清理和刪除流,所以若流極其多,那么內存的持續上漲是需要關注的。由此可見,系統的負載,首先需要被準確度量,也就是關注的是過載或超載(Overload)情況,這個問題也需要詳細說明。
What is Overload?超過系統負載就是超載或過載(Overload),這看起來是個簡單的問題,但實際上卻并不簡單,比如:
? CPU是否超過100%就是過載?不對,因為一般服務器會有多個CPU,也就是8個CPU的服務器,實際上能達到800%。? 那CPU是否不超過總CPU使用率,比如8CPU的服務器不超過800%就不會過載?不對,因為流媒體服務器不一定能用多核,比如SRS就是單核,也就是它最多跑100%。? 那是否SRS不超過100%使用率,就不會過載?不對,因為其他的進程可能也在消耗,不能只看SRS的CPU消耗。因此,對于CPU來說,知道流媒體服務器能消耗多少CPU,獲取流媒體服務器的CPU消耗,才能準確定義過載:
? 系統總CPU,超過80%認為過載,比如8CPU的服務器,總CPU超過640%就認為過載,一般系統的load值也升很高,代表系統很繁忙。? SRS每個進程的CPU,超過80%認為過載,比如8CPU的服務器總CPU只有120%,但SRS的進程占用80%,其他占用40%,那么此時也是過載。網絡帶寬,一般是根據以下幾個指標判斷是否過載,流媒體一般和流的碼率Kbps或Mpbs有關,代表這個流每秒是多少數據傳輸:
? 是否超過服務器出口帶寬,比如云服務器公網出口是10Mbps,那么如果平均碼率是1Mbps的直播流,超過10個客戶端就過載了。如果100個客戶端都來推拉流,那么每個客戶端只能傳輸100Kbps的數據,當然會造成嚴重卡頓。? 是否超過內核的隊列,在UDP中,一般系統默認的隊列大小只有256KB,而流媒體中的包數目和字節,在流較多時遠遠超過了隊列長度,會導致沒有超過服務器帶寬但是出現丟包情況,具體參考《SRS性能(CPU)、內存優化工具用法》(https://www.jianshu.com/p/6d4a89359352)這部分內容。? 是否超過客戶端的網絡限制,有時候某些客戶端的網絡很差,出現客戶端的網絡過載。特別是直播推流時,需要重點關注主播上行的網絡,沒經驗的主播會出現弱網等,導致所有人卡頓。磁盤,主要涉及的是流的錄制、日志切割以及慢磁盤導致的STW問題:
? 若需要錄制的流較多,磁盤作為最慢的設備,會明顯成為瓶頸。一般在系統設計時,就需要避免這種情況,比如64GB內存的服務器,可以分32GB的內存盤,給流媒體服務器寫臨時文件。或者使用較小的內存盤,用外部的程序比如node.js,開啟多線程后,將文件拷貝到存儲或發送到云存儲,可以參考srs-cloud(https://github.com/ossrs/srs-cloud)的最佳實踐。? 服務器的日志,在一些異常情況下,可能會造成大量寫入,另外如果持續累計不切割和清理,會導致日志文件越來越大,最終寫滿磁盤。SRS支持logrotate,另外docker一般也可以配置logrotate,通常會將日志做提取后(日志少可以直接采集原始日志),傳輸到云的日志服務做分析,本地只需要存儲短時間比如15天日志。? STW問題,寫磁盤是阻塞操作,特別是掛載的網絡磁盤(比如NAS),掛載到本地文件系統,而服務器在調用write寫入數據時,實際上可能有非常多的網絡操作,那么這種其實會更消耗時間。SRS目前應該完全避免掛載網絡磁盤,因為每次阻塞都會導致整個服務器STW(世界暫停)不能處理其他請求。內存主要是涉及泄露和緩存問題,主要的策略是監控系統整體的內存,相對比較簡單。
Special for Media Server除了一般的資源消耗,在流媒體服務器中,還有一些額外因素會影響到負載或者負載均衡,包括:
? 長連接:直播和WebRTC的流都是長時間,最長的直播可能超過2天,而會議開幾個小時也不是難事。因此,流媒體服務器的負載是具有長連接特性,這會對負載均衡造成很大的困擾,比如輪詢調度策略可能不是最有效的。? 有狀態:流媒體服務器和客戶端的交互比較多,中間保存了一些狀態,這導致負載均衡服務器無法直接在服務出現問題時,把請求直接給一臺新的服務器處理,甚至都不是一個請求,這個問題在WebRTC中尤其明顯,DTLS和SRTP加密的這些狀態,使得不能隨意切換服務器。? 相關性:兩個Web請求之間是沒有關聯的,一條失敗并不會影響另外一條。而在直播中,推流能影響所有的播放;在WebRTC中,只要有一個人拉流失敗或傳輸質量太差,盡管其他流都表現良好,但這個會議可能還是開不下去。這些問題當然不完全是負載和負載均衡問題,比如WebRTC支持的SVC和Simulcast功能,目的就是為了解決某些弱客戶端的問題。有些問題是可以通過客戶端的失敗重試解決,比如高負載時的連接遷移,服務器可以強制關閉,客戶端重試遷移到下一個服務器。
還有一種傾向,就是避免流媒體服務,而是用HLS/DASH/CMAF等切片,這就變成了一個Web服務器,上面所有的問題就突然沒有了。但是,切片協議實際上只能做到3秒,或者比較常見的5秒以上的延遲場景,而在1到3秒的直播延遲,或者500ms到1秒的低延遲直播,以及200ms到500ms的RTC通話,以及100ms之內的控制類場景,永遠都不能指望切片服務器,這些場景只能使用流媒體服務器實現,不管里面傳輸的是TCP的流,還是UDP的包。
我們在系統設計時,需要考慮這些問題,例如WebRTC應該盡量避免流和房間耦合,也就是一個房間的流一定需要分布到多個服務器上,而不是限制在一臺服務器。這些業務上的限制越多,對于負載均衡越不利。
SRS Overload現在特別說明SRS的負載和過載情況:
? SRS的進程:若CPU超過100%,則過載。SRS是單線程設計,無法使用多個CPU的能力(這個后面我會詳細展開講講)。? 網絡帶寬:一般是最快達到過載的資源,比如直播中達到1Gbps吞吐帶寬時可能CPU還很空閑,RTC由于同時是計算密集型,稍微有些差異。? 磁盤:除了非常少的路數的流的錄制,一般需要規避磁盤問題,掛載內存盤,或者降低每個SRS處理的流的路數。參考srs-cloud(https://github.com/ossrs/srs-cloud)的最佳實踐。? 內存:一般是使用較少的資源,在流路數特別特別多,比如監控場景不斷推流和斷開的場景,需要持續關注SRS的內存上漲。這個問題可以通過Gracefully Quit(https://github.com/ossrs/srs/issues/413#issuecomment-917771521)規避。特別說明一下SRS單線程的問題,這其實是個選擇,沒有免費的性能優化,多線程當然能提升處理能力,同時是以犧牲系統的復雜度為代價,同時也很難評估系統的過載,比如8核的多線程的流媒體服務器CPU多少算是過載?640%?不對,因為可能每個線程是不均勻的,要實現線程均勻就要做線程的負載調度,這又是更復雜的問題。
目前SRS的單線程,能適應絕大多數場景。對于直播來說,Edge可以使用多進程REUSEPORT方式,偵聽在同樣端口,實現消耗多核;RTC可以通過一定數量的端口;或者在云原生場景,使用docker跑SRS,可以起多個K8s的Pod,這些都是可選的更容易的方案。
Note: 除非是對成本非常敏感的云服務,那么肯定可以自己定制,可以付出這個復雜性的代價了。據我所知,幾個知名的云廠商,基于SRS實現了多線程版本。我們正在一起把多線程能力開源出來,在可以接受的復雜度范圍提升系統負載能力,詳細請參考https://github.com/ossrs/srs/issues/2188。
我們了解了流媒體服務器的這些負載,接下來該考慮如何分擔這些負載了。
Round Robin:Simple and RobustRound Robin是非常簡單的負載均衡策略:每次客戶端請求服務時,調度器從服務器列表中找到下一個服務器給客戶端,非常簡單:
server = servers[pos++ % servers.length()]
如果每個請求是比較均衡的,比如Web請求一般很短時間就完成了,那么這種策略是比較有效的。這樣新增和刪除服務器,上線和下線,升級和隔離,都非常好操作。
流媒體長連接的特點導致輪詢的策略并不好用,因為有些請求可能會比較久,有些比較短,這樣會造成負載不均衡。當然,如果就只有少量的請求,這個策略依然非常好用。
SRS的Edge邊緣集群中,在尋找上游Edge服務器時,使用的也是簡單的Round Robin方式,這是假設流的路數和服務時間比較均衡,在開源中是比較合適的策略。本質上,這就是上游Edge服務器的負載均衡策略,相當于是解決了總是回源到一臺服務器的過載問題。如下圖所示:
源站集群中,第一次推流時,Edge也會選擇一臺Origin服務器,使用的也是Round Robin策略。這本質上就是Origin服務器的負載均衡策略,解決的是Origin服務器過載問題。如下圖所示:
在實際業務中,一般并不會使用純粹的Round Robin,而是有個調度服務,會收集這些服務器的數據,評估負載,給出負載比較低或者質量高的服務器。如下圖所示:
如何解決Edge的負載均衡問題呢?依靠的是Frontend Load Balance策略,也就是前端接入側的系統,我們下面講常用的方式。
Frontend Load Balancer: DNS or HTTP DNS我們在Round Robin中重點介紹了服務內部的負載均衡,而直接對客戶端提供服務的服務器,一般叫做Frontend Load Balancer,情況會有點不太一樣:
? 若整個流媒體服務節點較少,而且是中心化部署,那么也可以用Round Robin的方式。在DNS中設置多個解析IP,或者HTTP DNS返回時隨機選擇節點,或者選擇相對較輕的負載的機器,也是可行的方案。? 在較多節點,特別是分布式部署的節點中,是不可能選擇Round Robin的方案,因為除了負載之外,還需要考慮用戶的地理位置,一般來說會選擇分配“就近”的節點。同樣DNS和HTTP DNS也能做到這點,一般是根據用戶的出口IP,從IP庫中獲取地理位置信息。其實DNS和HTTP DNS在調度能力上沒有區別,甚至很多DNS和HTTP DNS系統的決策系統都是同一個,因為它們要解決的問題是一樣的:如何根據用戶的IP,或者其他的信息(比如RTT或探測的數據),分配比較合適的節點(一般是就近,但也要考慮成本)。
DNS是互聯網的基礎,可以認為它就是一個名字翻譯器,比如我們在PING SRS的服務器時,會將ossrs.net解析成IP地址182.92.233.108,這里完全沒有負載均衡的能力,因為就一臺服務器而已,DNS在這里只是名字解析:
ping ossrs.netPING ossrs.net (182.92.233.108): 56 data bytes64 bytes from 182.92.233.108: icmp_seq=0 TTL=64 time=24.350 ms
而DNS在流媒體負載均衡時的作用,其實是會根據客戶端的IP,返回不同服務器的IP,而DNS系統本身也是分布式的,在播放器的/etc/hosts文件中就可以記錄DNS的信息,如果沒有就會在LocalDNS(一般在系統中配置或自動獲?。┎樵冞@個名字的IP。
這意味著DNS能抗住非常大的并發,因為并不是一臺中心化的DNS服務器在提供解析服務,而是分布式的系統。這就是為何新建解析時會有個TTL(過期時間),修改解析記錄后,在這個時間之后才會生效。而實際上,這完全取決于各個DNS服務器自己的策略,而且還有DNS劫持和篡改等操作,所以有時候也會造成負載不均衡。
因此HTTP DNS就出來了,可以認為DNS是互聯網的運營商提供的網絡基礎服務,而HTTP DNS則可以由流媒體平臺也就是各位自己來實現,就是一個名字服務,也可以調用一個HTTP API來解析,比如:
curl http://your-http-dns-service/resolve?domain=ossrs.net{["182.92.233.108"]}
由于這個服務是自己提供的,可以自己決定什么時候更新該名字代表的含義,當然可以做到更精確的負載,也可以用HTTPS防止篡改和劫持。
Note: HTTP-DNS的這個your-http-dns-service接入域名,則可以用一組IP,或者用DNS域名,因為它只有少數節點,所以它的負載相對比較好均衡。
Load Balance by VhostSRS支持Vhost,一般是CDN平臺用來隔離多個客戶,每個客戶可以有自己的domain域名,比如:
vhost customer.a {}vhost customer.b {}
如果用戶推流到同一個IP的服務器,但是用不同的Vhost,它們也是不同的流,播放時地址不同也是不同的流,例如:
? rtmp://ip/live/livestream?vhost=customer.a
? rtmp://ip/live/livestream?vhost=customer.b
Note:當然,可以直接用DNS系統,將IP映射到不同的域名,這樣就可以直接在URL中用域名代替IP了。
其實Vhost還可以用作多源站的負載均衡,因為在Edge中,可以將不同的客戶分流到不同的源站,這樣可以不用源站集群也可以擴展源站的能力:
vhost customer.a { cluster { mode remote; origin server.a; }}vhost customer.b { cluster { mode remote; origin server.a; }}
那么不同的Vhost實際上共享了Edge節點,但是Upstream和Origin可以是隔離的。當然也可以配合Origin Cluster來做,這時候就是多個源站中心,和Consistent Hash要實現的目標有點像了。
Consistent Hash在Vhost隔離用戶的場景下,會導致配置文件比較復雜,還有一種更簡單的策略,也可以實現類似的能力,那就是一致性Hash(Consistent Hash)。
比如,可以根據用戶請求的Stream的URL做Hash,決定回源到哪個Upstream或Origin,這樣就一樣可以實現同樣的隔離和降低負載。
實際應用中,已經有這種方案在線上提供服務,所以方案上肯定是可行的。當然,SRS沒有實現這個能力,需要自己碼代碼實現。
其實Vhost或者Consistent Hash,也可以配合Redirect來完成更復雜的負載均衡。
HTTP 302: Redirect302是重定向(Redirect),實際上也可以用作負載均衡,比如通過調度訪問到服務器,但是服務器發現自己的負載過高,那么就給定向到另外一臺服務器,如下圖所示:
Note: 除了HTTP 302,實際上RTMP也支持302,SRS的源站集群就是使用這個方式實現的。當然這里302主要用于流的服務發現,而不是用于負載均衡。
既然RTMP也支持302,那么在服務內部,完全可以使用302來實現負載的再均衡。若某個Upstream的負載過高,就將流調度到其他的節點,并且可以做多次302跳轉。
一般在Frontend Server中,只有HTTP流才支持302,比如HTTP-FLV或者HLS。而RTMP是需要客戶端支持302,這個一般支持得很少,所以不能使用。
另外,基于UDP的流媒體協議,也有支持302的,比如RTMFP,一個Adobe設計的Flash的P2P的協議,也支持302。當然目前用得很少了。
WebRTC目前沒有302的機制,一般是依靠Frontend Server的代理,實現后續服務器的負載均衡。而QUIC作為未來HTTP3的標準,肯定是會支持302這種基本能力的。而WebRTC逐漸也會支持WebTransport(基于QUIC),因此這個能力在未來也會具備。
SRS: Edge ClusterSRS Edge本質上就是Frontend Server,它可以解決以下問題:
? 直播的播放能力擴展問題,比如支持10萬人觀看,可以水平擴展Edge Server。? 解決就近服務的問題,和CDN起到的作用是一樣的,一般會選擇和用戶所在的城市部署。? Edge使用Round Robin方式連接到Upstream Edge,實現Upstream的負載均衡。? Edge本身的負載均衡,是依靠調度系統,比如DNS或HTTP-DNS。如下圖所示:
特別說明:
? Edge是直播流的邊緣集群,支持RTMP和HTTP-FLV協議。? Edge不支持切片比如HLS或DASH,切片協議使用Nginx或ATS分發。? 不支持WebRTC,WebRTC有自己的集群機制。由于Edge本身就是Frontend Server,因此一般不需要為了增加系統容量,再在前面掛Nginx或LB,因為Edge本身就是為了解決容量問題,而且只有Edge能解決合并回源的問題。
Note:合并回源,指的是同一個流只會回源一次,比如有1000個播放器連接到了Edge,Edge只會從Upstream獲取一路流,而不會獲取1000路流,這和透明Proxy是不同的。
當然,有時候還是需要前面掛Nginx或LB,比如:
1. 為了支持HTTPS-FLV或HTTPS-API,Nginx支持得更好,而且HTTP/2也支持。2. 減少對外的IP,比如多個服務器對外使用一個IP,這時候就需要有一臺專門的LB代理到后端多臺Edge。3. 在云上部署,只能通過LB提供服務,這是云產品的設計導致的,比如K8s的Service。除此之外,不應該在Edge前面再掛其他的服務器,應該直接由Edge提供服務。
SRS: Origin Cluster和Edge邊緣集群不同,SRS源站集群主要是為了解決源站擴展能力:
? 如果有海量的流,比如1萬路流,那么單個源站是扛不住的,需要多個源站形成集群。? 解決源站的單點問題,比如多區域部署,出現問題時自動切換到其他區域。? 切片協議的性能問題,由于寫入磁盤損耗性能較大,除了內存盤,還可以用多個源站降低負載。SRS源站集群是不建議直接對外提供服務,而是依靠Edge對外服務,因為使用了兩個簡單的技術:
? 流發現:源站集群會訪問一個HTTP地址查詢流,默認是配置為其他源站,也可以配置為一個專門的服務。? RTMP 302重定向,若發現流不在本源站,那么會定向到其他源站。Note: 其實Edge在回源前也可以先訪問流查詢服務,找到有流的源站后再發起連接。但是有可能流會切走,所以還是需要一個重新定位流的過程。
這個過程非常簡單,如下圖所示:
由于流始終只在一個源站上面,因此生成HLS切片時也會由一個源站生成,不需要做同步。一般使用共享存儲的方式,或者使用on_hls將切片發送到云存儲。
Note: 還有一種方式,使用雙流熱備,一般是兩個不同的流,在內部實現備份。這種一般需要自己實現,而且對于HLS、SRT和WebRTC都很復雜,SRS沒有支持也不展開了。
從負載均衡角度看源站集群,實際上是調度器實現的負載均衡,比如Edge回源時若使用Round Robin,或者查詢專門的服務應該往哪個源站推流,甚至當源站的負載過高,可以主動斷開流,讓流重推實現負載的重新均衡。
SRS: WebRTC CasecadeWebRTC的負載只在源站,而不存在邊緣的負載均衡,因為WebRTC的推流和觀看幾乎是對等的,而不是直播這種一對萬級別的不對等。換句話說,邊緣是為了解決海量觀看問題,而推流和觀看差不多時就不需要邊緣做負載均衡(直播可以用來做接入和跳轉)。
WebRTC由于沒有實現302跳轉,因此接入都沒有必要邊緣做負載均衡了。比如在一個Load Balance,也就是一個VIP后面有10臺SRS源站,返回給客戶端的都是同一個VIP,那么客戶端最終會落到哪個SRS源站呢?完全就是看Load Balance的策略,這時候并不能像直播一樣加一個邊緣實現RTMP 302的跳轉。
因此,WebRTC的負載均衡,就完全不是Edge能解決的,它本來就是依靠源站集群。一般在RTC中,這種叫做Casecade(級聯),也就是它們是平等關系,只是一級一級的路由一樣地連接起來,增加負載能力。如下圖所示:
這里和OriginCluster有本質的不同,因為OriginCluster之間并沒有媒體傳輸,而是使用RTMP 302讓Edge跳轉到指定的源站,因為源站的負載是可控的,它最多只有有限個Edge來回源取流。
而OriginCluster不適合WebRTC,因為客戶端需要直接連接到源站,這時候源站的負載是不可控的。比如在100人的會議中,每個流會有100個人訂閱,這時候需要將每個用戶分散到不同的源站上,和每個源站建立連接,實現推流和獲取其他人的流。
Note: 這個例子很罕見,一般100人互動的會議,會使用MCU模式,由服務器合并成一路流,或者選擇性的轉發幾路流,服務器內部的邏輯是非常復雜的。
實際上考慮WebRTC的常用場景,就是一對一通話,基本上占了80%左右的比例。那么這時候每個人都推一路流,播放一路流,是屬于典型的流非常多的情況,那么用戶可以完全連接到一個就近的Origin,而一般用戶的地理位置并不相同,比如在不同的地區或國家,那么源站之間級聯,可以實現提高通話質量的效果。
在源站級聯的結構下,用戶接入使用DNS或HTTP DNS協議訪問HTTPS API,而在SDP中返回源站的IP,因此這就是一次負載均衡的機會,可以返回離用戶比較接近而且負載較低的源站。
此外,多個源站如何級聯,若大家地區差不多,可以調度到一臺源站避免級聯,這可以節約內部的傳輸帶寬(在大量的同地區一對一通話時很值得優化),同時也增加了負載的不可調度性,特別是它們會演變成一個多人會議。
因此,在會議中,區分一對一的會議,和多人會議,或者限制會議人數,對于負載均衡實際上是非常有幫助的。如果能提前知道這是一對一會議,那么就更容易調度和負載均衡。很可惜的是,產品經理一般對這個不感興趣。
Remark: 特別說明,SRS的級聯功能還沒有實現,只是實現了原型,還沒有提交到開源倉庫。
TURN, ICE, QUIC, etc特別補充一下WebRTC相關的協議,比如TURN、ICE和QUIC等。
ICE其實不算一個傳輸協議,它更像是標識協議,一般指Binding Request和Response,會在里面帶有IP和優先級信息,來標識地址和信道的信息,用于多條信道的選擇,比如4G和WiFi都很好時優先選誰。還會用作會話的心跳,客戶端會一直發送這個消息。
因此ICE對于負載均衡沒有作用,但是它可以用來標識會話,和QUIC的ConnectionID作用類似,因此在經過Load Balance時可以起到識別會話的作用,特別是客戶端的網絡切換時。
而TURN協議其實是對Cloud Native非常不友好的協議,因為它是需要分配一系列的端口,用端口來區分用戶,這種是在私有網絡中的做法,假設端口無限,而公有云上端口往往是受限的,比如需要經過Load Balance這個系統時,端口就是有限的。
Note: 當然TURN也可以復用一個端口,而不真正分配端口,這限制了不能使用TURN直接通信而是經過SFU,所以對于SRS也沒有問題。
TURN的真正用處是降級到TCP協議,因為有些企業的防火墻不支持UDP,所以只能使用TCP,而客戶端需要使用TURN的TCP功能。當然了,也可以直接使用TCP的host,比如mediasoup就已經支持了,而SRS還沒有支持。
QUIC比較友好的是它的0RTT連接,也就是客戶端會緩存SSL的類似ticket的東西,可以跳過握手。對于負載均衡,QUIC更有效的是它有ConnectionID,那么經過LoadBalance時,盡管客戶端改變了地址和網絡,Load Balance還是能知道后端哪個服務來處理它,當然這其實讓服務器的負載更難以轉移了。
其實WebRTC這么復雜的一套協議和系統,講起來都是亂糟糟的,很糟心。由于100ms級別的延遲是硬指標,所以必須使用UDP和一套復雜的擁塞控制協議,再加上安全和加密也是基本能力,也有人宣稱Cloud Native的RTC才是未來,引入了端口復用和負載均衡,以及長連接和重啟升級等問題,還有那改得天翻地覆的結構,以及來攪局的HTTP3和QUIC……
或許對于WebRTC的負載均衡,有一句話是最適用的:世上無難事,只要肯放棄。
SRS: Prometheus Exporter所有負載均衡的前提,就是能知道負載,這依賴數據采集和計算。Prometheus(https://prometheus.io)就是做這個用的,它會不斷采集各種數據,按照它的一套規則,也可以計算這些數據,它本質上就是一個時序數據庫。
系統負載,本質上就是一系列的時序數據,會隨著時間變化。
比如,Prometheus有個node_exporter (https://github.com/prometheus/node_exporter),它提供了主機節點的相關時序信息,比如CPU、磁盤、網絡、內存等,這些信息就可以作為計算服務負載的依據。
每個應用服務,也會有對應的exporter,比如redis_exporter (https://github.com/oliver006/redis_exporter)采集Redis的負載數據,nginx-exporter(https://github.com/nginxinc/nginx-prometheus-exporter)采集Nginx的負載數據。
目前SRS還沒有實現自己的exporter,未來一定會實現,詳細請參考https://github.com/ossrs/srs/issues/2899。
以上就是關于雙流區個人如何申請pos機,流媒體服務器如何實現負載均衡的知識,后面我們會繼續為大家整理關于雙流區個人如何申請pos機的知識,希望能夠幫助到大家!
