详解srs流媒体服务器的集群
前言:
什么是集群
集群就是多台计算机或服务器等资源,联在一起像一台大机器一样工作。比如一群蚂蚁一起搬东西,这些蚂蚁就类似集群里的各个部分。
为什么要集群
- 性能更强:能把任务分到多个机器上做,一起处理更快,就像多人合作干活比一个人快。
- 更可靠:一台机器坏了,其他机器能顶上,服务不会停,像有备份队员。
- 方便变大:业务变忙,能加机器提升能力,好比房子小了加房间。
- 不怕灾难:机器分布在不同地方,一处出问题别处能接着干,如不同城市有仓库。
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 .源码解读之数据流转:从推流到转发
-
推流阶段
-
主播推流至Master:
- 主播通过RTMP协议将流推送到Master(如
rtmp://master/live/stream
)。 - Master的
SrsRtmpConn
接收推流请求,创建SrsLiveSource
实例管理流数据。
- 主播通过RTMP协议将流推送到Master(如
-
Master初始化转发器:
// SrsLiveSource::on_publish SrsForwarder* forwarder = new SrsForwarder(this); // 创建转发器 forwarder->start(); // 启动转发线程
-
转发阶段
-
建立RTMP连接:
- Master的
SrsForwarder
通过SrsSimpleRtmpClient
建立到Slave的RTMP连接。 - 发送RTMP握手(C0/C1/C2)和连接命令(
connect
、createStream
)。
- Master的
-
数据转发:
- 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); // 转发视频消息 }
- 转发过程中保持时间戳、消息类型等元信息不变。
- Master将接收到的RTMP消息(音频/视频)转发至Slave:
-
拉流阶段
-
客户端连接Slave:
- 客户端请求播放流(如
http://slave:8080/live/stream.flv
)。
- 客户端请求播放流(如
-
Slave响应请求:
- Slave的
SrsHttpFlvHandler
从本地缓存读取流数据,通过HTTP协议返回给客户端。
- Slave的
二 实现细节:关键类与函数
- 核心类结构
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. 主播推流 → SrsRtmpConn::do_publish() → 创建SrsLiveSource
2. SrsLiveSource → 初始化SrsForwarder → 连接Slave
3. 数据到达 → SrsLiveSource::on_audio/on_video() → 调用SrsForwarder对应回调
4. SrsForwarder → 通过SrsSimpleRtmpClient发送数据到Slave
- 转发优化机制
- 批量发送:将多个小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;}
}
- mode remote
功能:将当前服务器设置为 Edge 节点(即边缘缓存服务器)。
对比:
remote:作为 Edge 节点,从其他服务器(源站)拉流或转发流。
local:作为源站(默认值),直接处理推流和存储流数据。- origin 127.0.0.1:19350
功能:指定 源站(Origin Server)的地址。
作用:
当客户端请求播放 Edge 上的流时,若本地无缓存,Edge 会从该地址回源拉流。
当客户端推流到 Edge 时,Edge 会将流转发到该地址的源站。
多源站配置:可指定多个 origin,实现故障自动切换(如:主备源站)。- 客户端推流 → 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;}
}
相关文章:

详解srs流媒体服务器的集群
前言: 什么是集群 集群就是多台计算机或服务器等资源,联在一起像一台大机器一样工作。比如一群蚂蚁一起搬东西,这些蚂蚁就类似集群里的各个部分。 为什么要集群 性能更强:能把任务分到多个机器上做,一起处理更快&…...

ubuntu22.04 安装 SecureCRT8.7.3
用到的全部软件,都放在这个网盘里面了,自取。 链接: https://pan.baidu.com/s/1AR6Lj8FS7bokMR5IrLmsIw?pwd3dzv 提取码: 3dzv 如果链接失效了,关注公号:每日早参,回复:资源,即可免费获取&…...
Day 37
继续之前的学习 过拟合的判断 import torch import torch.nn as nn import torch.optim as optim from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.preprocessing import MinMaxScaler import time import matpl…...

libvirt设置虚拟机mtu实现原理
背景 云计算场景下,可以动态调整虚拟机mtu,提高虚拟机网络性能。设置虚拟机(VM)virtio网卡的MTU(Maximum Transmission Unit)涉及 宿主机(Host)、QEMU/KVM、vhost-net后端 和 虚拟机内部的virtio驱动之间的协作。 原理分析 1.libvirt设置mtu分析 libv…...

AstroNex空间任务智能控制研究与训练数据集
数据集概述 AstroNex空间任务智能控制研究与训练数据集是朗迪锋科技基于Multiverse平台精心打造的首个全面覆盖航天器智能控制全周期的综合数据集产品。该数据集汇集了轨道动力学、姿态控制、机器视觉、环境感知等多维度数据,为航天器智能算法研发提供丰富的训练与…...

汽车副水箱液位传感器介绍
汽车副水箱液位传感器是现代车辆冷却系统中不可或缺的关键部件,其核心功能在于实时监测冷却液存量,确保发动机在最佳温度范围内稳定运行。随着汽车电子化程度不断提升,这一看似简单的传感器已发展成为集机械、电子、材料技术于一体的精密装置,其工作原理与技术演进值得深入…...
Docker+MobaXterm+x11实现容器UI界面转发本地
本文记录了搭建一个可直接ssh访问的container,并可通过x11转发界面的实现过程 0.1 实验环境 PC:windows 11 Server:Ubuntu 18.04 Docker image:Ubuntu 18.04 1. 获取Ubuntu 18.04的镜像 使用Dockerfile获取镜像,对…...

IEEE出版|2025年智能制造、机器人与自动化国际学术会议 (IMRA2025)
【重要信息】 会议官网:www.icimra.com 会议时间: 2025年11月14日-16日 会议地点: 中国湛江 截稿日期:2025年09月16日(一轮截稿) 接收或拒收通知:文章投递后5-7个工作日 会议提交检索:EI Compendex, Scopus IEEE出版|2025年…...

EasyRTC嵌入式SDK音视频实时通话助力WebRTC技术与智能硬件协同发展
一、概述 在万物互联的数字化浪潮下,智能硬件已广泛渗透生活与工业领域,实时音视频通信成为智能硬件实现高效交互的核心需求。WebRTC作为开源实时通信技术,为浏览器与移动应用提供免插件的音视频通信能力,而EasyRTC通过深度优化音…...

Higress MCP Server 安全再升级:API 认证为 AI 连接保驾护航
Higress MCP Server 安全再升级:API 认证为 AI 连接保驾护航 Higress 作为一款强大的 AI 原生 API 网关,致力于铺设 AI 与现实世界之间最短、最安全、最具成本效益的连接路径。其核心能力之一便是支持将现有的 OpenAPI 规范无缝转换为 MCP Server&#…...
多个vue2工程共享node_modules
手头有多个vue2项目,它们每个都需要一个node_modules,拷贝起来超级麻烦。于是想到能否共享一个node_modules呢?? 方法其实挺多,我选择了一个较简单的:符号连接法(win11平台) 创建方法很简单:比…...
蓝桥杯178 全球变暖
题目描述 你有一张某海域 NxN 像素的照片,"."表示海洋、"#"表示陆地,如下所示: ....... .##.... .##.... ....##. ..####. ...###. ....... 其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上…...

多模态理解大模型高性能优化丨前沿多模态模型开发与应用实战第七期
一、引言 在前序课程中,我们系统剖析了多模态理解大模型(Qwen2.5-VL、DeepSeek-VL2)的架构设计。鉴于此类模型训练需消耗千卡级算力与TB级数据,实际应用中绝大多数的用户场景均围绕推理部署展开,模型推理的效率影响着…...
mysql 合集
mysql 日志主要分为三个日志:redo log、binlog、undo log; redo log 主要是用来mysql 奔溃恢复 redo log 主要是有一个机制是 设置刷盘机制: 通过innodb_flush_log_at_trx_commit控制刷盘策略: 1:每次事务提交都刷盘(…...
Zustand V5教程:Vanilla Store 与 useStore 使用详解 + 实战 Demo
Zustand 是一个轻量、灵活的状态管理库。自从 Zustand v4 推出 Vanilla Store 后,我们可以更优雅地在组件外(如 API 拦截器、工具函数)访问状态,同时在组件内继续享受响应式的状态订阅。 本教程将通过一个“登录状态管理”示例&a…...
docker 搭建php 开发环境 添加扩展redis、swoole、xdebug(1)
docker-compose搭建lnmp 先决条件 首先需要安装docker 安装docker-compost 1、创建lnmp工作目录 #创建三个目录 mkdir lnmp && cd lnmp mkdir -p nginx/conf php mysql/data lnmp/www#编写nginx 配置文件 nginx/conf/default.conf vim nginx/conf/default.confserv…...

人脸识别技术合规备案最新政策详解
《人脸识别技术应用安全管理办法》将于2025年6月1日正式实施,该办法从技术应用、个人信息保护、技术替代、监管体系四方面构建了人脸识别技术的治理框架,旨在平衡技术发展与安全风险。 一、明确技术应用的边界 公共场所使用限制:仅在“维护公…...
(16)高性能风控系统设计
文章目录 🚀 高性能风控系统设计:千万级QPS实时风控解决方案TL;DR🏗️ 系统整体架构💻 Java技术栈选型详解1️⃣ 接入层技术选型🔥 接入层代码示例 2️⃣ 规则引擎层技术选型🧠 规则引擎优化技巧 3️⃣ 数据…...

AStar低代码平台-脚本调用C#方法
修改报工表表单,右键定义弹出菜单,新增一个菜单项,并在点击事件脚本中编写调用脚本。 编译脚本,然后在模块代码里面定义这个方法: public async Task<int> on_call_import(DataRow curRow) {PrintDataRow(cur…...

企业级RAG技术实战指南:从理论到落地的全景解析
前言 在大模型技术日新月异的今天,检索增强生成(RAG)技术正成为企业突破AI应用瓶颈的关键利器。当传统AI系统还在处理结构化数据的泥潭中挣扎时,RAG技术已经打开了通向非结构化知识海洋的大门。这本《RAG技术实战指南》以独特的工…...
getline()跳过输入
std::getline(cin, s) 第一个参数传递的是输入流:istream(输入流的基类), ifstream, istrstream 的引用; 第二个参数传递的是本地字符串引用,即从输入流读出来的东西要存放的位置。 会跳过getline()的输入 cin >> ch; getline(cin, s…...

【八股战神篇】RabbitMQ高频面试题
简述RabbitMQ五种模式 ? 延伸 请介绍一下RabbitMQ的特点 延伸 简述RabbitMQ的发布与订阅模式 延伸 RabbitMQ 如何保证消息不丢失? 延伸 RabbitMQ 如何保证消息有序? 延伸 专栏简介 八股战神篇专栏是基于各平台共上千篇面经…...

高阶数据结构——红黑树实现
目录 1.红黑树的概念 1.1 红黑树的规则: 1.2 红黑树的效率 2.红黑树的实现 2.1 红黑树的结构 2.2 红黑树的插入 2.2.1 不旋转只变色(无论c是p的左还是右,p是g的左还是右,都是一样的变色处理方式) 2.2.2 单旋变色…...
互联网大厂Java求职面试:AI与大模型应用集成中的架构难题与解决方案
互联网大厂Java求职面试:AI与大模型应用集成中的架构难题与解决方案 面试场景:AI与大模型应用集成的架构设计 面试官:技术总监 候选人:郑薪苦(搞笑但有技术潜力的程序员) 第一轮提问:系统架…...

安卓学习笔记-声明式UI
声明式UI Jetpack Compose 是 Google 推出的用于构建 Android UI 的现代化工具包。它采用 声明式编程模型(Declarative UI),用 Kotlin 编写,用于替代传统的 XML View 的方式。一句话概括:Jetpack Compose 用 Kotlin…...

AI天气预报进入“大模型时代“:如何用Transformer重构地球大气模拟?
引言:从数值预报到AI大模型的范式变革 传统的天气预报依赖于数值天气预报(NWP, Numerical Weather Prediction),通过求解大气动力学方程(如Navier-Stokes方程)进行物理模拟。然而,NWP计算成本极高,依赖超级计算机,且难以处理小尺度天气现象(如短时强降水)。 近年来…...
本地项目如何设置https(2)——2025-05-19
在配置本地HTTPS时,安装mkcert工具本身是全局操作(安装在系统环境,与项目无关),但生成证书时需要进入项目目录操作。以下是具体说明: 安装 mkcert(全局操作) 安装位置:无…...

数据结构第3章 线性表 (竟成)
目录 第 3 章 线性表 3.1 线性表的基本概念 3.1.1 线性表的定义 3.1.2 线性表的基本操作 3.1.3 线性表的分类 3.1.4 习题精编 3.2 线性表的顺序存储 3.2.1 顺序表的定义 3.2.2 顺序表基本操作的实现 1.顺序表初始化 2.顺序表求表长 3.顺序表按位查找 4.顺序表按值查找 5.顺序表…...

JAVA面试复习知识点
面试中遇到的题目,记录复习(持续更新) Java基础 1.String的最大长度 https://www.cnblogs.com/wupeixuan/p/12187756.html 2.集合 Collection接口的实现: List接口:ArraryList、LinkedList、Vector Set接口:…...

项目中的流程管理之Power相关流程管理
一、低功耗设计架构规划(Power Plan) 低功耗设计的起点是架构级的电源策略规划,主要包括: 电源域划分 基于功能模块的活跃度划分多电压域(Multi-VDD),非关键模块采用低电压…...