單臺服務器作直播,總歸有單點風險,利用SRS的Forward機制 + Edge Server設計,能夠很容易搭建一個大規模的高可用集羣,示意圖以下html
源站服務器集羣:origin server cluster,能夠藉助forward機制,僅用少許的服務器,專用於處理推流請求。 nginx
邊緣服務器集羣:edge server cluster,能夠用N臺機器,從源站拉流,用於較大規模的實時播放。git
源站前置負載均衡(硬件或軟件負載均衡都行),上圖中用haproxy來實現tcp的軟負載均衡。github
邊緣服務器前置反向代理(好比:nginx),用於提供統一的播放地址,同時解決跨域問題,給客戶端拉流播放。redis
這樣架構的好處有如下:vim
一、無論是源站集羣,仍是連緣服務器集羣,都可水平擴展,理論上沒有上限。後端
二、源站能夠僅用較少的機器,好比2主2從,就能實現一個高可用且性能尚可的集羣(若是業務量不大,連slave server均可以省掉)api
三、邊緣服務器集羣,能夠根據實際用戶量隨時調整規模,另外hls切片,能夠放在edge server上切片,減輕源站服務器壓力。跨域
下面實戰一把,因筆者手頭資源有限,僅有2臺虛擬機(cent os 7.x),只能在每一個虛擬機上用不一樣的端口啓動多個srs實例,模擬master/slave/edge server (注:你們根據實際狀況,將下面的ip換成本身真實的ip地址)bash
ip | rtmp port | http api port | http server port | role |
10.*.72.62 | 1945 | 1995 | 8180 | master |
1946 | 1996 | 8181 | slave | |
1947 | 1997 | 8182 | edge | |
10.*.62.116 | 1945 | 1995 | 8180 | master |
1946 | 1996 | 8181 | slave | |
1947 | 1997 | 8182 | edge |
master配置:/usr/local/srs/conf/master.conf
listen 1945; max_connections 1000; pid ./objs/srs.master.pid srs_log_tank file; srs_log_file ./objs/srs.master.log; http_api { enabled on; listen 1995; } http_server { enabled on; listen 8180; dir ./objs/nginx/html; } stats { network 0; disk sda sdb xvda xvdb; } vhost __defaultVhost__ { forward 10.*.72.62:1946 10.*.62.116:1946; }
注:最後一段的forward,表示將視頻流轉發到2臺slave服務器
slave配置:/usr/local/srs/conf/slave.conf
listen 1946; max_connections 1000; pid ./objs/srs.slave.pid srs_log_tank file; srs_log_file ./objs/srs.slave.log; http_api { enabled on; listen 1996; } http_server { enabled on; listen 8181; dir ./objs/nginx/html; } stats { network 0; disk sda sdb xvda xvdb; } vhost __defaultVhost__ { }
edge配置:/usr/local/srs/conf/edge.conf
listen 1947; max_connections 1000; pid ./objs/srs.edge.pid srs_log_tank file; srs_log_file ./objs/srs.edge.log; http_api { enabled on; listen 1997; } http_server { enabled on; listen 8182; dir ./objs/nginx/html; } stats { network 0; disk sda sdb xvda xvdb; } vhost __defaultVhost__ { http_remux{ enabled on; mount [vhost]/[app]/[stream].flv; hstrs on; } hls{ enabled on; hls_path ./objs/nginx/html; hls_fragment 10; hls_window 60; } mode remote; origin 10.*.72.62:1945 10.*.62.116:1945 10.*.72.62:1946 10.*.62.116:1946; }
注:最後一段的origin 將全部master、slave均作爲視頻源(origin server),若是播放時,edge發現本身機器上沒有數據,會從origin配置的這些源站上去拉視頻流。
每臺虛擬機上,依次啓動:slave、master、edge(注:若是以前srs已在運行,先停掉原來的srs實例)
cd /usr/local/srs sudo ./objs/srs -c ./conf/slave.conf sudo ./objs/srs -c ./conf/master.conf sudo ./objs/srs -c ./conf/edge.conf
啓動成功後,建議先驗證下是否工做正常:
一、能夠用obs向每一個master或slave推流試試,好比 rtmp://10.*.72.62:1945/cnblogs/yjmyzz 或 rtmp://10.*.72.62:1946/cnblogs/yjmyzz,若是推流不報錯,說明master/slave工做正常
二、而後用vlc播放器,驗證從slave/edge這些服務器上拉流(好比 rtmp://10.*.72.62:1946/cnblogs/yjmyzz 或 rtmp://10.*.72.62:1947/cnblogs/yjmyzz,是否播放正常
若是上述2個步驟均驗證ok,接下來就是如何配置haproxy
爲了演示,能夠在其中一臺機器上安裝haproxy:
一、yum install haproxy (很是簡單)
二、vim /etc/haproxy/haproxy.cfg (修改配置文件)
global log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon stats socket /var/lib/haproxy/stats defaults mode tcp log global option tcplog option dontlognull option redispatch retries 3 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 listen srs-cluster bind *:1935 mode tcp balance roundrobin server master1 10.*.72.62:1945 server master2 10.*.62.116:1945
注:關鍵是最後一段,把本機1935端口,轉發到後端2臺master服務器的1945端口。
三、sudo systemctl restart haproxy (重啓haproxy)
重啓haproxy成功後,能夠用obs推流到 rtmp://haproxy_server_ip:1935/cnblogs/yjmyzz 試下推流是否正常,若是ok,能夠嘗試把其中一臺master停掉,看看是否有影響。
最後是nginx出場了,ngnix的安裝相似haproxy,yum install nginx 便可,關鍵是配置:
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; upstream srs{ server 10.*.72.62:8182; server 10.*.62.116:8182; } server { listen 80; server_name localhost; location ~ /* { proxy_pass http://srs; add_header Cache-Control no-cache; add_header Access-Control-Allow-Origin *; } location / { root /Users/jimmy/html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } include servers/*; }
注:新增一個upstream用於指定要轉發的edge服務器節點,而後在location ~ /* 這裏proxy_pass 指定upstream的名字便可(location ~ /* 切記要寫在 location / 前面)。這樣配置後,訪問 http://nginx_server_ip/cnblogs/yjm.flv 理論上就能轉到後端的edge服務器。