1.引入
首先我们要知道一般情况下使用FFMPEG或者其他工具推流后,是不能直接推送到播放器,而是必须要经CDN服务器的转发,即后端流媒体服务器,如SRS,所以传统的视频流媒体结构有:推流端、视频流媒体服务器、播放端。
当我们用SRS搭建好视频流媒体服务器之后,很快就会遇到一个问题:如何支持多人同时在线拉流浏览视频?比如如何支持上万个用户同时拉流
2.srs集群
单个srs
SRS3开始支持了完善的源站和边缘集群。SRS早就支持了Edge边缘集群,应用于少数推流和众多比如百万人观看的CDN场景;加上Origin源站集群,可以支持众多的推流比如安防摄像头,以及实现源站的热备。
最简单的视频服务,推一个流,只有一个播放器消费流,我们只需要一个SRS Origin源站服务就可以,启动配置文件如下
listen 1935;
max_connections 1000;
vhost __defaultVhost__ {
}
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,而从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如何用多个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进程,这样可以将边缘服务器的多核能力用起来