RTP直播分发服务器集群方案

RTP直播分发服务器集群方案


一、背景与目标

       当前支持RTMP接入的服务器比较多,SRS、Nginx-rtmp、FMS、WOWza、RED5等等,但支持RTP接入并支

集群化的并不多,为此我们开发了一款RTP接入的直播分发服务器集群,集群具备以下特点:

           

(1)超低延时,采用RTP(UDP)作为传输层解决方案,系统延时低于300ms,适用于实时互动等应用场景。

(2)抗丢包能力强,保证RTP上行线路和下线线路在弱网情况下依旧有良好表现。

(3)基于虚拟的房间(教室)模式,支持在房间内广播音视频(RTP)和信令(TCP),支持私有音视频和信令交互。

(4)集群模式,集群扩展简便,规模可大可小,灵活配置,避免单点故障。

(5)负载均衡,将流量(客户端)合理的分配到集群的各台服务器上。

(6)自带CDN加速功能,为每个客户端优选最佳的服务器资源,保障用户体验。

(7)支持服务器同步推送RTMP流到指定第三方流媒体服务器,可以与SRS、FMS、Nginx-rtmp等结合实现RTP、RTMP、HLS流的同步播出,从而实现全平台的直播。

(8)高并发、高稳定性。

(9)纯C++实现,代码精简高效。提供日志和远程telnet登录,管理和维护便捷。


二、架构说明



                                                                              图1 一种典型的集群部署情况


1、总体数据流介绍


图1是一种典型的集群部署方案,接下来我们将对图中各个服务的作用、客户端的登陆流程、数据的分发流程分别予以介绍。

集群由Domain服务和Media服务组成,Domain服务有几个用途:

(A)充当DNS的功能,为客户端CDN优选提供候选的Media服务器IP地址集合,后面详细介绍。

(B)房间管理、用户管理、TCP信令的转发。房间是一个虚拟的概念,同一个房间可以跨多台Media服务器。

同样,进入同一个房间的用户也会根据其自身情况登录到不同的Media服务器。Domain管理着这种关系,当一条房

间广播信令从客户端A发往Media时,Media除了在本服务器上分发给该房间内所有用户外,还将消息上报

Domain,Domain将消息分发给创建了该房间的其他Media服务器,后者将消息分发给各自旗下的该房间客户端

们。私有信令的流程与广播信令稍有不同,当私有消息从客户端A发往Media时,若Media发现目标客户端B也位于本

服务器上,则直接转发,否则发往Domain服务器,Domain服务器查询到客户端B所在的Media服务器并转发之。

(C)维护与集群内众多Media服务器的连接,与Media形成CS架构。

       需要说明,Domain服务并不和音视频数据打交道,无数据和计算压力。另外,客户端与Domain之间并无TCP

或者RTP的通讯,客户端只与其登录的Media服务器存在TCP长连接和RTP数据通讯。


       Media服务负责所有音视频的处理并与客户端直接打交道,同一个Domain旗下的所有Media之间创建了P2P的

RTP通讯链接,用于音视频数据在Media之间的传输。图1中,当发布客户端A的音视频数据上行到Media服务器A

时,Media将在本地房间内广播该音视频数据,同时将数据转发给其他Media服务器,后者在各自的本地房间内向客

户端下发。对于接收端与发布端位于同一台Media或者不同Media,数据的传输路径始终是最短的,没有多余的传输

链路。


       按照架构设计,同一个房间内有多个音视频发布者,且服务端不做多画面合成时(画面数较少),各个发布者可

以登录于不同的Media服务器。观众客户端将通过与其Media服务器之间的唯一AV通道获得各个发布者的音视频数

据,业务层根据索引来区分音视频数据在属于哪一个发布者,从而显示到对应的位置上。这种情况下,Media之间的

地位是对等的。


       当服务器端需要做多画面合成与混音时,要求房间的所有音视频发布者登录到同一台Media,此时Media可以称

为“代理”,其他Media则称为“中转”。这种情况下,所有房间的所有发布者登录到代理服务器,而所有的观众则

登录到众多中转服务器上。


       一个集群内Media服务器的数量是不受限制的,当观众规模增长较大到原有系统无法支撑时,只需要扩展新的

Media即可,整个部署过程非常简单。正因为“房间”或者称为“教室”是一个跨服务器的存在,所以可以实现不限

房间数量,单个房间不限客户端的数量的效果(当然要想在业务层限制也比较简单)。需要说明集群的规模可大可小,

最小的情况下只需要单台服务器即可,此时Domain服务和Media服务均部署于同一台机器。


2、负载均衡 & CDN加速


       集群内的各台物理机的处理性能(CPU、内存等)以及网络带宽各不相同,因此能够服务的客户端数量也不尽相

同,通过配置文件,我们可以指定每台Media最大支持的客户端数量。当某台机器的负载(处理性能或者带宽)消耗

达到较高的比率时,应该优先将客户端安排到其他机器上。Domain维护了域下每台Media的当前负载值以及最大支

持负载值,所以可以合理的影响客户端的登录情况。


       CDN的重要性不言而喻,当前国内的网络状况相当复杂,形成了“南电信北联通”的局面,还有长城宽带、铁

通、教育网也占有较大市场份额。由于跨运营商的数据传输在运营商内部是需要费用结算的,所以运营商主观上并不

保障跨运营商的传输质量,音视频媒体传输经常面临延时大、丢包率高等特点。即便是同一个运营商,用户登录就近

的服务器也比登录地域上更远的服务器获得更好的传输质量,传输路径最短化是CDN的目标之一。曾有机构做过相关

的统计,接入相同的运营商并且地理位置最近的情况下,网络延时最优,小于15ms。跨省同运营商的网络延时为

25~50ms,同省跨运营商则达到了50~100ms,跨省更高。

       

       常见的CDN方案是通过用户使用的DNS服务器来判断客户端所在的网络位置,从而返回对应的服务器IP。这种方

式的缺点:第一,调度的准确度是完全依赖用户配置的DNS(通常运营商指定),而这些DNS大多数是省级的,比如

它只能确定为广东电信,但常常分不出来是广东广州电信还是广东深圳电信。第二,我们不得不在流媒体服务器之外

通过另外的WEB服务器实现DNS的IP判定。第三,这种静态的分配方式也许并不能真实的反映线路的传输状况,服务

器本身可能出现故障、线路也可能遇上蓝翔,所以需要动静结合。


       综上所述,我们在域服务器上实现了一套自己的CDN优选服务,客户端在登录Media之前,将访问Domain服务

器,Domain服务器综合考虑当前各台Media机器的资源利用率、运营商类型、地域分布情况以及客户端的运营商类

型、地域等生成一组可供客户端使用的候选Media服务器IP地址集合。客户端在拿到该集合后,使用UDP进行测速,

并根据测速结果得到最优Media服务器IP地址。需要说明的,Media服务器工作在“代理”状态时,建议使用BGP多

线服务器,因为各种网络类型的发布客户端均需要登录该服务器。


3、抗丢包 & 实时性

       

       服务器集群是建立在RTP-FEC-QOS传输层基础上,RTP-FEC-QOS的最大优势就是在保证低延时指标同时能较

强的抵抗弱网(WIFI、3G、4G)带来的乱序、抖动、丢包等问题。具体的说明请参考RTP-FEC-QOS传输层相关文

章。这里主要说明传输链路的创建情况。



                                                             图2 客户端与服务器媒体传输通道的建立


       客户端登陆Media服务器时,服务器为其从端口库中分配一组连续的4个端口,分别用于音视频RTP和RTCP(这

些端口将在客户端下线时回收)并使用这组端口创建一个服务器类型的RTP-FEC-QOS传输对象。客户端TCP登录成

功并收到服务器分配的端口后将使用这组端口创建一个客户端类型的RTP-FEC-QOS传输对象(客户端本地端口和远

端端口都使用这组分配端口,这样可以实现客户端的单机多实例)。至此,客户端和服务器之间的媒体通道建立成

功,即便双方没有音视频数据交互,通道也会有定时的内部NAT保活包。


4、集群隔离

    

       一组Domain-Media的组合称呼为一个域,同一套服务器集群里可以部署多个域,它们之间将采用不同的端口段

以避免冲突。不同域之间是完全独立隔离的,这样我们可以将不同的用户局点隔离开来,避免相互影响,大家共用硬

件和网络资源,节省成本。多域隔离的另一个好处是可以实现外网正式版本与测试版本共存,测试环境更加真实。


5、全平台播放支持

 

       RTP协议需要客户端才能予以支持,PC浏览器、移动端浏览器(微信)只支持RTMP、HLS、HTTP-FLV、DASH

等流格式,为了做到全平台的播放支持,SRTP-Server支持向用户配置的指定地址推送RTMP流,借助第三方流媒体

服务器FMS、SRS、Nginx-rtmp便可以实现全格式输出。



                             

                                                        图3  支持rtmp流推送的一种情况

        图3是SRTP-Server支持RTMP推送的一种情况,我们在Media服务所在的服务器上部署了Nginx-rtmp,这样

Media在收到媒体数据后只需要向rtmp://127.0.0.1/live/roomXX地址(XX为Media自动添加的房间号)推送媒体流

即可,这样本地socket延时也非常小。需要说明的是WEB播放器也应该使用websocket通过Domain获得优选的

Media服务器,这样我们可以通过Domain控制整体的负载。


6、维护手段

      

      集群中的Domain、Media服务除了提供基础日志输出外,还支持远程telent连接,通过telnet可以实现命令行的交互。


7、更多

 

 更多相关的文章请参考 www.mediapro.cc



  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用 Python 实现本地 RTP 数据包通过 RTSP 服务器转发的代码示例: ```python import socket # 本地 RTP 地址和端口 local_rtp_ip = "127.0.0.1" local_rtp_port = 5004 # RTSP 服务器地址和端口 rtsp_server_ip = "192.168.1.100" rtsp_server_port = 554 # 建立 RTP 套接字 rtp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) rtp_socket.bind((local_rtp_ip, local_rtp_port)) # 建立 RTSP 连接 rtsp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) rtsp_socket.connect((rtsp_server_ip, rtsp_server_port)) # 发送 RTSP SETUP 请求 rtsp_setup_request = "SETUP rtsp://{}/stream1 RTSP/1.0\r\nCSeq: 1\r\nTransport: RTP/AVP;unicast;client_port={}-{}\r\n\r\n".format(rtsp_server_ip, local_rtp_port, local_rtp_port + 1) rtsp_socket.send(rtsp_setup_request.encode()) # 接收 RTSP SETUP 响应 rtsp_setup_response = rtsp_socket.recv(1024) print(rtsp_setup_response.decode()) # 发送 RTSP PLAY 请求 rtsp_play_request = "PLAY rtsp://{}/stream1 RTSP/1.0\r\nCSeq: 2\r\nSession: {}\r\nRange: npt=0.000-\r\n\r\n".format(rtsp_server_ip, rtsp_setup_response.decode().split("Session: ")[1].split("\r\n")[0]) rtsp_socket.send(rtsp_play_request.encode()) # 接收 RTSP PLAY 响应 rtsp_play_response = rtsp_socket.recv(1024) print(rtsp_play_response.decode()) # 开始接收 RTP 数据包并转发到 RTSP 服务器 while True: rtp_data = rtp_socket.recv(2048) rtsp_socket.send(rtp_data) ``` 代码解释: 1. 首先,我们定义了本地 RTP 地址和端口,以及 RTSP 服务器地址和端口。 2. 然后,我们建立了 RTP 套接字,并绑定到本地 RTP 地址和端口。 3. 接着,我们建立了 RTSP 连接,并发送 RTSP SETUP 请求,以请求服务器分配 RTP 端口。 4. 我们接收了 RTSP SETUP 响应,并从中提取了会话 ID。 5. 然后,我们发送 RTSP PLAY 请求,以请求服务器开始发送 RTP 数据包。 6. 我们接收了 RTSP PLAY 响应,并开始接收本地 RTP 数据包。 7. 最后,我们将接收到的 RTP 数据包转发到 RTSP 服务器。 注意,该代码示例仅适用于单个 RTP 流。如果您需要转发多个 RTP 流,您需要为每个流建立单独的 RTP 套接字和 RTSP 连接,并使用不同的端口。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值