目录
1 前言
2 集群方案
3 集群搭建
3.1 搭建步骤
3.2 搭建流程
3.2.1 集群机器端口开放
3.2.2 集群机器ip固化
3.2.3 提交容器为镜像文件
3.2.4 启动节点
3.2.5 配置源站
3.2.6 配置边缘站
3.2.7 启动srs服务
4 集群服务测试
4.1 测试用例
1 前言
上一篇已经分享了,如何基于srs-bench来进行srs的压测测试。同时我们也得到一个结论,单台的srs服务器,是撑不住2000个直播链接的。所以这边来讲解下如何实现srs的集群。
为了避免读者读完本篇骂我,我先声明下:
目前srs基于webrtc协议拉流的集群还不支持,但是可以支持rtmp、flv、hls等协议的拉流集群。
本篇分享的是rtmp拉流、推流集群如何实现以及验证了webrtc暂不支持拉流集群。
2 集群方案
SRS官方提供了SRS集群的方案。
个人理解后简化出如下产物:
- SRS主要功能分推流和拉流两个
- 单台服务器情况,SRS既负责推流也负责拉流
- 集群场景,将推流和拉流两个功能分离开来,即一台SRS要么只推流,要么只拉流,分如下三种:
- 单推流、多拉流
- 多推流、单拉流
- 多推流、多拉流
- 集群节点可以动态上线和下线
根据上面的信息,我选定的集群方案是多推流、多拉流:
注:
接受推流的SRS是源站(Origin)
接受拉流的SRS是边缘站(Edge)
3 集群搭建
3.1 搭建步骤
按照如下步骤完成SRS集群搭建:
步骤 | 备注 |
了解SRS流 | 多路流是怎么来的,怎么选择播放哪路流: 以推流为例子: 推流的url为:rtmp:ip:port/appName/appStream 其中appName表示当前的流属于哪个应用的 其中appStream表示当前的流属于哪个流的 因此通过差异化appName和appStream就可以将流分多路。 拉流的时候,不管协议是哪种,在拉流的url里头都有appName和appStream,通过指定这两个要素,就可以拉取对应的流了。 |
了解Origin和Edge的流同步方式 | Players为啥选择随机一个Edge都可以播放: 通过给Edge配置origin参数来实现 |
提交webRtc的docker容器为基础镜像 | 集群需要用到多个节点,这样操作,就不用重复安装srs的环境以及srs |
启动四个webrtc的容器 | 两台做源站,两台做边缘站 |
修改源站配置 | 增加: cluster { #集群的模式,对于源站集群,值应该是local。 mode local; #是否开启源站集群 origin_cluster on; #源站集群中的其他源站的HTTP API地址 coworkers 192.168.0.114:9090; } |
修改边缘站配置 | 增加: cluster { #集群的模式,对于边缘集群,值应该是remote。 mode remote; #源站集群中所有源站流地址 origin 192.168.0.114:19350 192.168.0.115:19350; } |
启动四台webrtc服务 | 因为配置文件同一个,因此启动命令一样: cd /home/git/srs/trunk/ && ./objs/srs -c ./conf/rtc2rtmp.conf |
测试 | 给两个源站推不同的流, 通过边缘站1查看流1; 通过边缘站2查看流1; 通过边缘站1查看流2; 通过边缘站2查看流2; |
通过docker查看四个站点的负载 | docker stats |
3.2 搭建流程
按照上面的设计步骤,现在开始实施搭建过程。
3.2.1 集群机器端口开放
在该专栏的第二篇,作者已经解释过了srs里头各个端口的作用。
如果是单一srs服务节点的话,那么建议开放所列举的所有的端口,但是如果是服务集群的话,那么建议是按需来开放节点的端口。
按照节点的功用不一样,节点的开放端口不一样,具体如下:
节点类别 | 端口 | 说明 |
源站(ORIGIN) | 1935 | 推流使用rtmp |
边缘站(EDGE) | 8080 1985 1935 | WebRTC播放器使用8080,初始化webRTC使用1985 rtmp协议拉流 |
因为集群的节点的端口是要开放到docker的宿主机上的,所以部分节点的默认映射到宿主机的端口就得做修改,具体修改后的端口,在下面3.2.2会一起附上,需要注意的是,每个docker容器节点内部的服务的端口不做修改,只是修改映射到宿主机上的端口号,比如:
docker run -d -p 1935:1936 --privileged=true 5de52d772a3c /usr/sbin/init
-- 上面这个命令,就是将宿主机(本机)的1935端口映射到docker容器的1936上
3.2.2 集群机器ip固化
因为要用到集群,那么每台机器的ip就要固定掉,不然集群配置的时候,不好配置:比如重启下docker容器,ip就变了,集群的配置就失效了。因为使用的是docker,所以我们只要类似如下命令让docker启动容器的时候,指定好容器的ip即可:
docker run -d -p 1935:1935 -p 8080:8080 -p 1985:1985 -p 80:80 -p 8000:8000/udp --ip 172.18.0.2 --privileged=true 5de52d772a3c /usr/sbin/init
本次集群是两个边缘站,两个源站,因此,每个站点的ip和端口如下:
Name | Ip | 端口映射 | Docker容器启动命令 | |
Origin1 | 172.17.0.1 | 1935->1935 | docker run -d -p 1935:1935 --privileged=true xxxxx /usr/sbin/init | |
Origin2 | 172.17.0.2 | 1936->1935 | docker run -d -p 1936:1935 --privileged=true xxxxx /usr/sbin/init | |
edge1 | 172.17.0.3 | 8080>8080 1985->1985 1937->1935 | docker run -d -p 1985:1985 -p 8080:8080 -p 1937:1935 --privileged=true xxxxx /usr/sbin/init | |
edge2 | 172.17.0.4 | 8081>8080 1986->1985 1938->1935 | docker run -d -p 1986:1985 -p 8081:8080 -p 1938:1935 --privileged=true xxxxx /usr/sbin/init |
注1:
有人可能会问,上面的xxxxx是什么东西,别着急,因为前面我已经搭建过了srs的单机版服务,所有下面会进行将已经搭建好的srs容器提交为镜像文件,xxxx就是这个镜像文件,下面步骤会讲到。
注2:
很多人可能会像平常使用centos一样的,去修改docker-centos的容器的ip地址,比如通常我们通过修改:/etc/sysconfig/network-scripts/ifcfg-ens33,去设置centos的静态ip地址,但是这个其实在docker里头是无效的,每次容器重新启动的时候,都会重新生成新的ip,如果这块不懂的话,建议再去看看docker容器相关的知识点。
3.2.3 提交容器为镜像文件
在该专栏的第二篇里头,我们已经完成了对srs单机版的搭建,所以搭建出来的容器,已经配置好了所有srs相关的内容,不管是源站还是边缘站都可以基于这个来搭建。为了让边缘站和源站重复利用之前搭建好的容器,我们需要把之前搭建好的容器转成镜像。
使用如下命令将容器提交为基础镜像(文件比较大,所以提交过程需要一点时间,大概十几秒吧):
docker commit 容器ID 镜像名称
# eg: docker commit xxxxxx baseImage
然后就可以通过docker images 查看到我们刚刚提交成功的镜像文件了。
3.2.4 启动节点
按照3.2.2的启动命令分别启动所有的集群节点。
3.2.5 配置源站
源站和边缘站的配置是不一样的,源站配置的是推流的信息。
配置方式如下:
在172.17.0.1的源站配置:
# 因为要集群webrtc协议,所以要修改的是rtc2rtmp.conf文件
cd /home/git/srs/trunk/conf
vi rtc2rtmp.conf
# vhost __defaultVhost__里头新增如下配置
cluster {
#集群的模式,对于源站集群,值应该是local。
mode local;
#是否开启源站集群
origin_cluster on;
#源站集群中的其他源站的HTTP API地址 如果其他源站有多个,中间用空格隔开,比如:172.17.0.2:9090 172.17.1.2:9090
coworkers 172.17.0.2:9090;
}
在172.17.0.2的源站配置:
# 因为要集群webrtc协议,所以要修改的是rtc2rtmp.conf文件
cd /home/git/srs/trunk/conf
vi rtc2rtmp.conf
# vhost __defaultVhost__里头新增如下配置
cluster {
#集群的模式,对于源站集群,值应该是local。
mode local;
#是否开启源站集群
origin_cluster on;
#源站集群中的其他源站的HTTP API地址 如果其他源站有多个,中间用空格隔开,比如:172.17.0.2:9090 172.17.1.2:9090
coworkers 172.17.0.1:9090;
}
3.2.6 配置边缘站
边缘站需要配置源站的信息,因为边缘站负责拉流,那么拉流要从哪里拉流,这个就是边缘站需要配置的内容。因为源站有集群,所以边缘站需要的流可能来自其中任意一个源站,因此需要给边缘站配置所有的源站节点信息:
在172.17.0.3的边缘站配置:
# 因为要集群webrtc协议,所以要修改的是rtc2rtmp.conf文件
cd /home/git/srs/trunk/conf
vi rtc2rtmp.conf
# vhost __defaultVhost__里头新增如下配置
cluster {
#集群的模式,对于边缘集群,值应该是remote。
mode remote;
#源站集群中所有源站流地址
origin 172.17.0.1:1935 172.17.0.2:1935;
}
在172.17.0.4的边缘站配置:
# 因为要集群webrtc协议,所以要修改的是rtc2rtmp.conf文件
cd /home/git/srs/trunk/conf
vi rtc2rtmp.conf
# vhost __defaultVhost__里头新增如下配置
cluster {
#集群的模式,对于边缘集群,值应该是remote。
mode remote;
#源站集群中所有源站流地址
origin 172.17.0.1:1935 172.17.0.2:1935;
}
你可能会注意到了,边缘站的配置是一样的,没错,所有的边缘站的配置都是一样的,因为都是要从所有的潜在的源站拉流,所以配置都是一样的。
3.2.7 启动srs服务
因为所有的节点的配置文件同一个,因此启动命令一样:
cd /home/git/srs/trunk/ && ./objs/srs -c ./conf/rtc2rtmp.conf
至此,集群就搭建完毕了。
4 集群服务测试
下面要进行集群的测试。
4.1 测试用例
给两个源站推不同的流:
rtmp://localhost:1935/live/1
rtmp://localhost:1936/live/2
通过边缘站1查看流1;
通过边缘站2查看流1;
通过边缘站1查看流2;
通过边缘站2查看流2;
分别通过rtmp协议拉流和通过webRTC拉流
rtmp拉流:
rtmp://localhost:1937/live/1
rtmp://localhost:1937/live/2
rtmp://localhost:1938/live/1
rtmp://localhost:1938/live/2
webrtc拉流:
webrtc://localhost:1985/live/1
webrtc://localhost:1985/live/2
webrtc://localhost:1986/live/1
webrtc://localhost:1986/live/2
在验证过程通过命令docker stats来查看四个站点的负载。
经过使用obs和vlc分别来充当推流和拉流的工具,
使用http://localhost:8080/players/rtc_player.html充当webrtc协议的拉流工具,
验证了上面的测试用例的结果如下:
站点 | 负载状态 | WEBRTC拉流 | RTMP拉流 |
Origin1 | 推流会波动 | ||
Origin2 | 推流会波动 | ||
Edge1 | 拉流会波动 | 黑屏 | 正常播放 |
Edge2 | 拉流会波动 | 黑屏 | 正常播放 |
最终测试结果为:SRS可以支持集群,但是webrtc协议不支持SRS集群。
上述结论通过docker监测四站点负载,同时通过跟rtmp协议拉流做比对,结合官网文档得到的。
开篇之前,我就已经声明了,目前的SRS还不支持webrtc协议的集群,下一篇分享srs基于flv、hls协议的集群。