当前位置: 首页 > news >正文

详解srs流媒体服务器的集群


前言:
什么是集群
集群就是多台计算机或服务器等资源,联在一起像一台大机器一样工作。比如一群蚂蚁一起搬东西,这些蚂蚁就类似集群里的各个部分。

为什么要集群

  1. 性能更强:能把任务分到多个机器上做,一起处理更快,就像多人合作干活比一个人快。
  2. 更可靠:一台机器坏了,其他机器能顶上,服务不会停,像有备份队员。
  3. 方便变大:业务变忙,能加机器提升能力,好比房子小了加房间。
  4. 不怕灾难:机器分布在不同地方,一处出问题别处能接着干,如不同城市有仓库。

1 SRS集群之forward

1.1 基本架构

1. 什么是Forward模式?
Forward(转发)是SRS(Simple Realtime Server)实现集群功能的一种基础模式,其核心思想是:

  • 推模式(Push-based):由一个中心节点(Master)主动将直播流数据推送到多个目标节点(Slave)。
  • 单向数据流:数据流向固定为 Master → Slave,Slave节点不主动请求数据。

#2. 为什么需要Forward模式?
Forward模式主要解决以下问题:

  • 负载分担:将客户端拉流请求分散到多个Slave节点,避免单个服务器过载。
  • 就近访问:通过在多地部署Slave节点,降低客户端访问延迟(如CDN边缘节点)。
  • 容灾备份:当Master故障时,可快速切换到其他Slave节点继续提供服务。

3. 核心组件

  • Master节点
    • 接收原始推流(如主播端推送的RTMP流)。
    • 负责将流数据转发给所有配置的Slave节点。
    • 通常部署在中心机房或源站。
  • Slave节点
    • 被动接收Master转发的流数据。
    • 为客户端提供拉流服务(如HTTP-FLV、HLS播放)。
    • 可部署在边缘机房或CDN节点。

4 SRS Forward模式架构详解

在这里插入图片描述

  • 推流到 Master:推流者(主播)将直播流推送到 Master 节点 。比如在图中,主播通过 PUSH 操作把流推给 Master 。
  • Master 转发到 Slave:不管 Slave 节点有没有人观看对应的流,Master 都会把接收到的直播流转发给所有配置好的 Slave 节点 。例如图中 Master 会把流 Forward 给 Salve 1 、Salve n 等节点 。
  • 用户连接 Slave 观看:用户的播放端连接到 Slave 节点来观看直播 。图中显示有用户连接到 Slave 节点,每个 Slave 节点可支持 1000 连接 。

五 SRS Forward模式架构存在问题

  • 带宽浪费:如果部分 Slave 节点没人观看直播,但 Master 仍会向其推送流,就会造成带宽浪费 。如图中提到,若 King 老师直播,有 10 台 Slave,但只有 1 台有人看,其他 9 台也会收到流,浪费带宽 。
  • Master 带宽压力:随着 Slave 节点数量增加,Master 的出口带宽压力会增大。因为要给每个 Slave 都转发相同的流 。
    六 SRS Forward模式架构应用场景
    Forward 模式适合搭建小型集群 。在小型场景中,节点数量相对较少,带宽浪费和 Master 压力在可接受范围内。如果是大型集群,这种模式可能就不太合适,更推荐使用 edge 模式等 。

1.2 实战配置

1 .源码解读之数据流转:从推流到转发

  1. 推流阶段

  2. 主播推流至Master

    • 主播通过RTMP协议将流推送到Master(如rtmp://master/live/stream)。
    • Master的SrsRtmpConn接收推流请求,创建SrsLiveSource实例管理流数据。
  3. Master初始化转发器

    // SrsLiveSource::on_publish
    SrsForwarder* forwarder = new SrsForwarder(this);  // 创建转发器
    forwarder->start();  // 启动转发线程
    
  4. 转发阶段

  5. 建立RTMP连接

    • Master的SrsForwarder通过SrsSimpleRtmpClient建立到Slave的RTMP连接。
    • 发送RTMP握手(C0/C1/C2)和连接命令(connectcreateStream)。
  6. 数据转发

    • Master将接收到的RTMP消息(音频/视频)转发至Slave:
      // SrsForwarder::on_audio
      int SrsForwarder::on_audio(SrsSharedPtrMessage* msg) {return publish_message(msg);  // 转发音频消息
      }// SrsForwarder::on_video
      int SrsForwarder::on_video(SrsSharedPtrMessage* msg) {return publish_message(msg);  // 转发视频消息
      }
      
    • 转发过程中保持时间戳、消息类型等元信息不变。
  7. 拉流阶段

  8. 客户端连接Slave

    • 客户端请求播放流(如http://slave:8080/live/stream.flv)。
  9. Slave响应请求

    • Slave的SrsHttpFlvHandler从本地缓存读取流数据,通过HTTP协议返回给客户端。

二 实现细节:关键类与函数

  1. 核心类结构
class SrsForwarder {
private:SrsLiveSource* source;  // 关联的媒体源SrsSimpleRtmpClient* rtmp_client;  // RTMP客户端,用于连接Slavepublic:int start();  // 启动转发器int on_meta_data(SrsSharedPtrMessage* msg);  // 处理元数据int on_audio(SrsSharedPtrMessage* msg);  // 处理音频int on_video(SrsSharedPtrMessage* msg);  // 处理视频int publish_message(SrsSharedPtrMessage* msg);  // 发送消息到Slave
};
  1. 关键函数调用流程
1. 主播推流 → SrsRtmpConn::do_publish() → 创建SrsLiveSource
2. SrsLiveSource → 初始化SrsForwarder → 连接Slave
3. 数据到达 → SrsLiveSource::on_audio/on_video() → 调用SrsForwarder对应回调
4. SrsForwarder → 通过SrsSimpleRtmpClient发送数据到Slave
  1. 转发优化机制
  • 批量发送:将多个小RTMP消息合并为一个大包,减少网络IO次数。
  • 丢包重传:通过RTMP的ACK机制检测丢包,自动重传丢失的数据包。
  • 心跳检测:定期发送心跳包(如Ping Request),维持与Slave的连接。

3 master配置

listen              1935;
max_connections     1000;
pid                 ./objs/srs.master.pid;
daemon              off;
srs_log_tank        console;
vhost __defaultVhost__ {forward {enabled on;destination 127.0.0.1:19350;}
}

** 4 slave 配置**

listen              19350;
max_connections     1000;
pid                 ./objs/srs.slave.pid;
daemon              off;
srs_log_tank        console;
http_server {enabled         on;listen          8080;  # HTTP服务端口dir             ./objs/nginx/html;  # 静态文件目录
}vhost __defaultVhost__ {http_remux {enabled         on;mount           [vhost]/[app]/[stream].flv;  # 挂载路径hstrs           on;  # 减少首包延迟
}
}

2 SRS 的 Edge 模式

2.1 Edge的基本知识

整体架构与角色

  • 源站(Origin Server):作为直播流的原始提供方,负责接收推流并存储、管理直播流数据,是整个架构的核心数据源。比如在一些大型直播场景中,源站可能部署在资源丰富的中心机房,像北京 BGP 机房 。
  • 边缘服务器(Edge Server):分布在网络边缘位置(如各个省份的机房),起到缓存和分发直播流的作用。边缘服务器配置为remote模式,并指定origin(源站 IP),成为源站的缓存节点。
    在这里插入图片描述
    推流原理
    当用户进行推流操作时,推流数据首先到达边缘服务器**。边缘服务器不会对推流数据做过多处理,而是直接将流转发给源站**。例如,湖南的电信 ADSL 用户推流,若直接推到北京 BGP 源站可能因网络距离等因素效果不佳,此时在湖南电信机房部署的边缘服务器,就可以接收用户推流,并将流转发给北京源站。这样做的好处是利用边缘服务器靠近推流用户的地理位置优势,降低推流过程中的网络延迟和不稳定因素,确保推流能稳定到达源站 。
    拉流原理
  • 缓存命中情况:当用户请求播放边缘服务器上的直播流时,边**缘服务器会先检查自身是否有该流的缓存。如果有缓存,边缘服务器直接将缓存中的流数据发送给客户端,这样客户端就能快速获取到直播内容,**减少等待时间,提高播放体验。
  • 缓存未命中情况:若边缘服务器没有缓存该流数据,它会向源站发起一路回源链接,从源站获取数据。并且,多个客户端同时请求观看同一流时,边缘服务器也只会发起一路回源链接,从源站取到数据后,源源不断地放到自己的缓存队列中,再依次分发给各个客户端。例如全国 32 个省每个省部署 10 台边缘服务器,每个省 1 台边缘服务器有 2000 用户观看,总共 64 万用户观看时,回源链接只有 320 个(32x10)。这种机制大大减少了源站的负载压力,同时实现了大规模的直播流分发 。

与 Forward 模式的区别

  • Forward 模式:适用于将一路流主动分发给多个目标服务器的场景,无论目标服务器是否有客户端请求,都会持续推送流数据,可能会造成带宽浪费 。
  • Edge 模式:按需回源拉流,只有在有客户端请求且边缘服务器没有缓存时才会回源,更适用于大规模集群且流众多、需要按需获取数据的场景。在配置多个服务器的情况下,正常时只使用一台,故障时才进行切换。

应用场景
CDN/VDN 大规模集群:客户众多且流也众多,通过 Edge 模式按需回源,能有效利用网络资源,降低骨干网络带宽压力,实现高效的大规模分发。
小规模集群但流较多的情况:同样可以利用 Edge 模式按需获取流数据,避免不必要的资源消耗 。
骨干带宽低的情况:可以通过部署多层 Edge 服务器,利用边缘服务器的处理能力,降低上层 BGP 带宽的使用压力 。

故障切换原理
边缘服务器可以指定多个源站。当正在使用的源站出现故障时,边缘服务器能够自动检测到,并切换到下一个源站获取流数据。在这个切换过程中,用户的观看体验不会受到明显影响,几乎觉察不到源站的切换,保障了服务的高可用性和容错性。

相关源码分析

源码核心模块

1. 关键类与职责
类名职责
SrsEdgeForwarder推流转发器,负责将客户端推流数据转发至源站。
SrsEdgeIngester拉流获取器,负责从源站拉取流数据。
SrsSource流源管理,维护流状态(是否可发布、是否有缓存)。
SrsRequest请求上下文,携带流名称、推流者信息等元数据。

推流核心逻辑(源码片段)

// srs_app_edge.cpp
srs_error_t SrsEdge::acquire_publish(SrsRtmpConn* conn, SrsSourceInfo* info)
{SrsRequest* req = info->req;// 检查流是否可发布(边缘节点不做实际检查,直接转发)if (!source->can_publish(info->edge)) {return srs_error_new(ERROR_SYSTEM_STREAM_BUSY, "stream busy");}// 边缘节点特殊处理:启动转发器,不存储流数据if (info->edge) {return source->on_edge_start_publish();}// 源站处理:存储流数据、触发转码等return source->on_publish();
}

面试关键点

  • Edge与源站的区别:Edge节点不存储流数据,仅转发;源站负责实际存储和处理。
  • 并发控制can_publish() 方法防止同一流被重复发布。

拉流核心逻辑(源码片段)

// srs_app_edge.cpp
srs_error_t SrsEdge::play(SrsRequest* req, SrsSource** psource)
{// 1. 尝试从本地获取流SrsSource* source = SrsSource::find(req->vhost, req->app, req->stream);// 2. 本地无缓存,从源站拉流if (!source) {SrsEdgeIngester* ingester = new SrsEdgeIngester(this, req);return ingester->start();  // 启动拉流协程}// 3. 本地有缓存,直接返回*psource = source;return srs_success;
}

面试关键点

  • 按需回源:仅当本地无缓存时触发回源,多个客户端共享同一回源连接。
  • 单例模式:同一流在Edge节点仅存在一个 SrsSource 实例。

2.2 实战

oringin文件

listen              19350;
max_connections     1000;
pid                 ./objs/origin.pid;
daemon              off;
srs_log_tank        console;
http_server {enabled         on;listen          8081;dir             ./objs/nginx/html;
}
vhost __defaultVhost__ {http_remux {enabled     on;mount       [vhost]/[app]/[stream].flv;}
}       

edge 文件

listen              1935;
max_connections     1000;
pid                 objs/edge.pid;
daemon              off;
srs_log_tank        console;
http_server {enabled         on;listen          8080;dir             ./objs/nginx/html;
}
vhost __defaultVhost__ {cluster {mode            remote;origin          127.0.0.1:19350;}http_remux {enabled     on;mount       [vhost]/[app]/[stream].flv;}
}
  1. mode remote
    功能:将当前服务器设置为 Edge 节点(即边缘缓存服务器)。
    对比:
    remote:作为 Edge 节点,从其他服务器(源站)拉流或转发流。
    local:作为源站(默认值),直接处理推流和存储流数据。
  2. origin 127.0.0.1:19350
    功能:指定 源站(Origin Server)的地址。
    作用:
    当客户端请求播放 Edge 上的流时,若本地无缓存,Edge 会从该地址回源拉流。
    当客户端推流到 Edge 时,Edge 会将流转发到该地址的源站。
    多源站配置:可指定多个 origin,实现故障自动切换(如:主备源站)。
  3. 客户端推流 → Edge节点(1935) → 转发至源站(127.0.0.1:19350)

edge2文件

listen              1935;
max_connections     1000;
pid                 objs/edge2.pid;
daemon              off;
srs_log_tank        console;
vhost __defaultVhost__ {cluster {mode            remote;origin          127.0.0.1:19350;}
}

相关文章:

  • sharding jdbc的使用,如何在Spring中实现数据库的主从分离、分库分表等功能
  • day022-定时任务-故障案例与发送邮件
  • Redis核心数据结构操作指南:字符串、哈希、列表详解
  • php 实现基数排序
  • PromQL 从基础入门教程
  • html5视频播放器和微信小程序如何实现视频的自动播放功能
  • Linux编辑器——vim的使用
  • 优雅草最新实战项目技术Discuz X3.5电子签约插件开发项目实施方案优雅草·卓伊凡
  • QT 框架学习笔记
  • 什么是 WPF 技术?什么是 WPF 样式?下载、安装、配置、基本语法简介教程
  • 用户配置文件(Profile)
  • 网络安全方向在校生有哪些证书适合考取?
  • 安卓开发用到的设计模式(3)行为型模式
  • EasyRTC嵌入式SDK音视频实时通话助力WebRTC技术与智能硬件协同发展
  • kubernetes网络详解(内部网络、Pod IP分配、CNI)
  • FlagOS 新里程:开源面向多种硬件架构的统一AI 编译器 FlagTree
  • 机器学习笔记【Week6】
  • Redis 集合、有序集合与通用命令详解
  • [Vue] ref及其底层原理
  • 单片机(MCU)的 IO 口静电、浪涌、电压异常等保护
  • 鞍钢贴吧/seo推广优化培训
  • 厦门手机网站建设公司/品牌推广外包
  • html+css代码大全/seo站长助手
  • 企业自己的网站/淘宝推广平台有哪些
  • 大良网站建设基本流程/青岛seo服务
  • 如何建立网站快捷方式到桌面/seo做什么网站赚钱