Nginx RTC服务SFU级联的实现

前言

级联解决的主要问题是媒体分发。

横向扩展:在大主播场景下,一个主播对应成千上万的观众,服务器的性能和带宽限制了观众人数的上限,为了能够支持更多的观众,需求从单个服务器扩展到集群服务器。

分发质量:同样对于大规模观众来说,不同的观众分布在不同的地域,可能出现跨国或跨省传输,还有就是不同的观众对应的电信网络运营商不同,也会影响媒体分发传输质量,所以需要观众可以就近接入高质量的服务器节点。

这些不同的服务器节点组成了服务器集群,服务器间的媒体分发采用级联的形式。

由于网上介绍为什么需要级联SFU的文章已经很多了,本文不再做重复介绍。本文的主要内容侧重于对级联的具体实现的一些思考。

实现方案

RTMP直播级联的实现

首先我们看下当前已经非常成熟的RTMP直播级联的实现。我选取Nginx-RTMP作为参考,因为nginx-rtmp-module在github上的star数量11.5k,fork为3.3k,并且nginx-rtmp-module已经在广泛的应用,具有代表性。

RTMP的级联通过relay module实现,如果要实现动态级联,可以借助notify module,根据调度服务返回的302状态码及relay地址进行动态的级联。

RTC的SFU级联方案对比

协议 复杂性 扩展性 延迟 抗丢包 可靠性 性能 端口复用
RTP/RTCP 中等 中等
QUIC 中等 中等 中等
私有TCP 中等
私有UDP 中等 中等 中等

由于我们的业务需求,不是做通用的视频云业务,在播放端更多的是借助第三方CDN厂商的节点能力。我们当前是自建源站服务,重点是保证推流端和源站的服务。为了支持更低延迟的直播服务,所以需要开发部署支持webrtc的源站流媒体服务。

通过对比不同的SFU级联协议实现,并结合我们的业务特性。由于我们的源站集群的网络环境属于内网,内网中服务器间的网络环境优异,延迟低、丢包率低、可靠性强,并且现在操作系统对TCP的收发数据方面是有优化的,发送相同的数据比UDP耗费更少的CPU时间,所以源站间不同SFU级联采用的是TCP协议进行级联。而且服务器间发送数据可以不使用加密解密,这样可以降低延迟和CPU消耗。

针对CDN厂商进行回源时,可以考虑采用RTP/RTCP、QUIC进行级联。优化点是可以将UDP Packet加解密模块跳过,节约服务器性能。

TCP级联的实现

级联拉流
推流 NGINX RTC中继 NGINX RTC源站 NGINX RTC播放边缘 播放器 推流 Relay Push Create TCP Connection 发送流信息(ssrc、media等) 是否收到流信息 如果没收到流信息,则再次请求流信息 发送流信息 创建 Relay Session Send RTP Packet By TCP Relay Pull Create TCP Connection 请求流信息(ssrc、media等) 发送流信息 是否收到流信息 如果没收到流信息,则再次请求流信息 发送流信息 创建 Relay Session Send RTP Packet By TCP 拉流 推流 NGINX RTC中继 NGINX RTC源站 NGINX RTC播放边缘 播放器

QUIC级联的实现

新版Nginx中支持quic的实现,但是还没有正式合并到稳定的主版本里。当前SFU集群不存在长距离跨国传输,所以QUIC相对于TCP的优势在当下的业务场景里并不存在明显的优势。所以Nginx RTC服务的QUIC级联后续再进行实现。

级联调度

你可能感兴趣的:(Nginx,C/C++,RTC,nginx,音视频,运维,webrtc,rtc)