Docker 部署 SRS 流媒体服务器:从零到生产级实践
我第一次把 SRS 装进 Docker,起因很简单——当时测试服务器上的依赖已经乱成一锅粥,CentOS 里同时装着好几个版本的 GCC 和库文件,源码编译动不动就报错。SRS 是一个开源的实时音视频流媒体服务器,支持 RTMP、WebRTC、HLS、HTTP-FLV、SRT 这些主流协议,做直播间、在线课堂、IoT 摄像头低延迟拉流都非常合适,但源码部署光是编译环境就劝退了很多人。换成 Docker 之后,一条命令就能起一个干净的 SRS 实例,换个版本也只是换一下镜像标签,这个体验差异是决定性的。
这篇文章适合两类人:一类是刚接触流媒体服务的运维或后端同学,想知道怎么把 SRS 快速跑起来并且稳定运行;另一类是已经跑过 RTMP,但还没打通 WebRTC、鉴权、自定义配置这些进阶玩法的开发者。我会从最基础的容器启动讲到生产环境的 Compose 编排,再讲到公网 WebRTC 和常见坑位排查,全文都基于我实际部署过的路径,照着操作基本能复现。
1. 为什么用 Docker 部署 SRS,而不是直接编译源码
1.1 SRS 是什么,这个容器镜像解决了什么真实问题
SRS 全称 Simple Realtime Server,是一个用 C++ 写的开源流媒体服务端。它的定位很务实:把复杂的流媒体接入协议封装成一个服务,你推流给它,它帮你转成各种协议分发给播放端。很多搞在线教育、电商直播、安防监控的团队都会用它,因为不需要自己从零实现 RTMP 或 WebRTC,只要把流推上去,SRS 就能帮你切换协议、录制、转封装。
不过 SRS 的原生部署有一个让不少人头疼的地方:它真的很依赖编译环境。从源码安装要跑
./configure
、
make
,如果机器上缺少依赖库或者版本不对,编译期报错能查半天。有些老版本还需要手动处理 openssl 版本、ffmpeg 依赖,这些事情和流媒体本身没有半点关系,但就是会挡住你进入正题。Docker 镜像把编译好的二进制和环境一起打包了,不用管宿主机装了什么,拉下来就能用。
1.2 镜像版和源码版对比,我实际感受到的差异
单从功能上看,源码版和 Docker 版跑的其实是同一个 SRS,但你真正用的时候会发现三个差别非常大的地方:
-
升级和回滚的成本完全不在一个量级。源码版升级要重新拉代码、重新编译;Docker 版只需要换镜像 tag,比如从
ossrs/srs:4切到ossrs/srs:5,启动新容器就行。如果新版有兼容性问题,一秒钟就能切回旧镜像。 - 环境隔离让排查问题的范围大大缩小。流媒体涉及网络端口、UDP 转发、系统文件描述符,这些一旦和宿主机上的其他服务混在一起,出现故障时很难定位。Docker 至少把进程、日志、文件目录都圈在一个容器里。
- 交付与迁移特别省事。在一台机器上调试好的 Compose 文件,复制到另一台服务器,改一下 IP 和域名就能跑。我用源码版部署时,换机器意味着重新走一遍编译流程,时间成本差好几倍。
为了直观,我列一个常用对比:
| 对比项 | 源码编译部署 | Docker 部署 |
|---|---|---|
| 首次部署时间 | 视机器性能,可能几十分钟到两小时 | 拉镜像后基本秒级启动 |
| 依赖环境 | 需手动解决 GCC、openssl 等依赖 | 镜像内已封装 |
| 版本切换 | 重新下载编译或 patch 代码 | 换镜像 tag 即可 |
| 资源隔离 | 与宿主机耦合,进程难限制 | 天然隔离,可限 CPU 内存 |
| 配置文件管理 | 散落在部署目录 | 通过挂载统一管理 |
| 典型故障面 | 编译失败、动态库缺失、端口冲突 | 端口映射、容器网络配置错误 |
1.3 什么情况下不建议用 Docker 跑 SRS
我虽然推荐 Docker,但不是所有场景都适合容器化。如果你的需求是二次开发 SRS 底层协议栈,要改它的 C++ 核心代码、加自定义编译选项,那容器化只会增加调试难度,这时候直接源码编译反而灵活。
另一种情况是主机资源极其紧张。容器本身会带来少量额外开销,虽然通常可以忽略,但如果你的服务器只有 512MB 内存,而且同时要跑很多服务,裸跑 SRS 可能比容器多挤出一点资源。不过话说回来,SRS 本身比较轻量,这种极限场景并不多见。
还有一类情况要特别小心:如果你们的网络环境本身处于多层 NAT 之后,容器会进一步增加端口映射的复杂度,尤其是 WebRTC 这种依赖 UDP 和公网地址协商的协议,排在容器后面会更难调通。后面我会专门讲这个问题。
2. 配置落盘:端口、网络模式和存储挂载,部署前一次性想清楚
2.1 需要提前留出的端口清单
SRS 不是一个只有一个端口的小服务,它按模块监听多个端口。Docker 部署时,端口映射是第一个很容易踩坑的地方。我先说一个典型的最小端口集:
| 端口 | 协议 | 用途 | 说明 |
|---|---|---|---|
| 1935 | TCP | RTMP 推流/拉流 | 必须开放给推流端 |
| 1985 | TCP | HTTP API | 用于查询流状态、调用管理接口 |
| 8080 | TCP | HTTP 服务 | HLS 拉流、HTTP-FLV 拉流的入口 |
| 8000 | UDP | WebRTC 音视频传输 | 做 WebRTC 必须要开放 |
| 8085 | UDP | SRT 推流 | 使用 SRT 时才需要 |
注意这里说的是 Docker 映射到宿主机的端口,可以是宿主机的任意空闲端口,不一定非得和容器内保持一致。比如你不想让 SRS 占用宿主机的 8080 端口,可以映射成
8088:8080
。但是有一个原则我建议遵守:如果后面要做的集群或边缘转发,尽量把映射关系固定下来写在配置里,不要每次启动临时编一个端口。
实际规划端口时要考虑的不只是 SRS 本身,还有防火墙。很多 Linux 服务器上有 iptables 或 firewalld,光是容器端口映射通了还不够,宿主机防火墙没放行 UDP 8000,WebRTC 就会连不上。这个检查项我放在第 5 节详细说。
2.2 bridge 网络和 host 网络,别一上来就选错
Docker 的默认网络模式是 bridge,容器内端口通过
-p
映射出来,外部访问走宿主机 IP 加映射端口。这个模式好处是安全、灵活,缺点是容器内的 SRS 看到的网络地址和宿主机不一样,对 WebRTC 这种需要协商候选地址的协议会有一点麻烦。
host 网络模式下,容器直接共享宿主机的网络栈,端口不需要映射,SRS 能拿到宿主机真实的外网 IP。这在公网服务器上确实更省事,尤其是 WebRTC,因为候选地址不用做地址转换。
不过我要提醒一句:在 Windows 和 macOS 的 Docker Desktop 上,host 网络支持比较受限,行为跟 Linux 下很不一样。如果你是在本地开发机上测试,建议还是用 bridge 模式,配合端口映射来跑,这样更直观。到了公网 Linux 服务器,如果追求 WebRTC 好调,可以用 host 模式,但要用 Docker Compose 里的端口映射限制其他业务访问,别把所有端口都裸奔在公网上。
实际使用中我的默认做法是:本地开发走 bridge,生产机如果只有单个 SRS 实例,优先 host;如果一台机器要跑多个流媒体服务或多个 SRS 实例,那就回到 bridge,用不同端口区分。
2.3 配置文件和录制目录的挂载方式
SRS 容器的工作目录是
/usr/local/srs
,默认配置文件在
conf/srs.conf
。你当然可以进容器里去改配置,但这样改的东西容器一删就没了,所以必须把配置挂载出来管理。
推荐的挂载结构是这样的:
/opt/srs/
├── srs.conf
└── html/
└── live/
启动时把
srs.conf
挂载到容器内的
conf/srs.conf
,再把宿主机
html
目录挂到容器内的
/usr/local/srs/objs/nginx/html
。这样 HLS 切片和录制文件都会写到宿主机目录,方便备份和清理。
日志也值得提前考虑。SRS 默认会把日志写到
objs/srs.log
文件,但容器化之后最好把日志输出到 stdout,让
docker logs
来接管,这样日志轮转、收集都统一了。在配置里加上这一行:
log_tank console;
这个配置会让 SRS 把日志打到标准输出,Docker 的日志驱动就能把日志收集起来,再配合 Loki 或 ELK 这种日志系统就很顺。
如果你必须保留文件日志,可以挂载一个宿主机的目录到容器内日志位置,避免容器重启后日志丢失。不过按照个人经验,生产环境我更推荐 console 输出,省心得多。
3. 第一条命令跑起来:从零推流到播放验证
3.1 拉取镜像并启动一个最小实例
前置条件是你已经装好了 Docker,并且能正常拉取镜像。我先用官方镜像跑一个最小化实例,不做任何自定义配置:
docker run -d \
--name srs \
-p 1935:1935 \
-p 1985:1985 \
-p 8080:8080 \
-p 8000:8000/udp \
ossrs/srs:5
这里用的镜像 tag 是
ossrs/srs:5
,对应 SRS 5.x 版本。SRS 6、SRS 7 也有发布,但 5 是目前使用最广泛的稳定版本,文档和社区讨论最丰富,建议不要一上来就追最新版。
启动后看日志:
docker logs -f srs
正常情况下你会看到 SRS 的启动日志,里面会列出各个模块监听的端口:
rtmp_server listen on :1935
http_server listen on :8080
rtc_server listen on udp://:8000
注意这里有一个很容易忽略的细节:官方镜像自带的配置文件可能没有启用 HLS 模块,默认主要保证 RTMP 和 WebRTC 基础能力。也就是说,第一次启动能快速验证核心功能,但生产级协议支持还是要按第 4 节的自定义配置文件来。
3.2 用 ffmpeg 推第一路流
启动容器后,最直接的验证方式就是推流。在宿主机上准备一个视频文件,用 ffmpeg 循环推流:
ffmpeg -re -stream_loop -1 -i test.mp4 \
-c copy -f flv rtmp://localhost/live/demo
推流地址里的
live
是应用名,
demo
是流名,你可以随意命名。SRS 收到推流后,这条流的完整地址就是:
rtmp://localhost/live/demo
如果想看这条流有没有被正确接收,可以用 ffplay 拉流验证:
ffplay rtmp://localhost/live/demo
能看到画面,说明最核心的 RTMP 链路已经打通。
这里有个新手容易犯的错误:ffmpeg 推流默认会等待输入,如果你用了
-stream_loop -1
,要注意加
-re
,否则文件会被以最大速度推完,播出来就是快进画面。
-re
的意思是按原始帧率读取,模拟实时推送,这样 SRS 才会把它当作一路持续性直播流。
3.3 用 HLS 和 API 来确认服务状态
RTMP 推通之后,再验证一下 HTTP 侧的转发能力。如果配置里启用了 HTTP-FLV,可以直接用这个地址播放:
http://localhost:8080/live/demo.flv
如果启用了 HLS,则看这个地址:
http://localhost:8080/live/demo.m3u8
在浏览器里打开 m3u8 链接,如果能出来视频画面,说明 HLS 切片和分发都正常。
另一个非常实用的验证办法是查 SRS 的 HTTP API。SRS 在 1985 端口提供了一套 JSON API,查询当前流列表:
curl http://localhost:1985/api/v1/streams
返回的 JSON 里会包含流的 ID、推流地址、活跃客户端数等信息。这个 API 后面做监控和鉴权回调时也会经常用到,现在先把它验证通了,后面就不会手忙脚乱。
3.4 验证阶段最容易被忽略的流卡顿问题
第一次跑通后,很多人接下来遇到的是同样的画面:推流没问题,但拉流一直卡顿、缓冲。这时候别急着怀疑 SRS 配置,先确认两个基本面:
第一,磁盘 IO 是否正常。RTMP 拉流本身不怎么会写磁盘,但如果启用了 DVR 录制或 HLS,就会持续写文件。硬盘是机械盘或者刚跑完别的任务,写入延迟会直接影响切片进程。
第二,带宽是不是够。一路 1080p 的流如果码率是 8Mbps,播放端、推流端、转发链路里任何一环带宽不足,都会造成缓冲。SRS 本身不产生数据,它只是搬运和转封装,瓶颈经常在推流端上传、播放端下载或者网络节点上。
验证阶段建议先推一路低码率视频,比如用
-b:v 1M
指定码率,确认链路没问题后再上高码率流,这样能快速隔离到底是谁的问题。
4. 生产级组合拳:Compose 编排、自定义配置和打通 WebRTC
4.1 用 Docker Compose 接管 SRS 生命周期
单纯用
docker run
管理单个容器没问题,但一涉及到配置文件挂载、环境变量、容器重启策略,命令就会变得很长很难维护。我习惯从一开始就用 Compose 管理。
下面是一个可以直接用的
docker-compose.yml
:
services:
srs:
image: ossrs/srs:5
container_name: srs
restart: unless-stopped
ports:
- "1935:1935"
- "1985:1985"
- "8080:8080"
- "8000:8000/udp"
volumes:
- ./srs.conf:/usr/local/srs/conf/srs.conf
- ./html:/usr/local/srs/objs/nginx/html
command: ["./objs/srs", "-c", "conf/srs.conf"]
注意这里的关键点:配置文件通过 volume 覆盖了容器内默认配置,而
command
显式指定用这个配置启动。
restart: unless-stopped
保证机器重启后容器能自动拉起来,这个在生产环境几乎是必备的。
html
目录不需要提前建好,Docker 会自动创建,但最好在宿主机给一个明确的路径,方便排查 HLS 切片文件到底有没有生成。
启动命令也很简单:
docker compose up -d
4.2 一份实用的自定义 srs.conf
Compose 只是把容器管起来了,真正决定 SRS 行为的是
srs.conf
。我在生产上用过的配置大概长这样:
listen 1935;
max_connections 1000;
daemon off;
log_tank console;
http_server {
enabled on;
listen 8080;
dir ./objs/nginx/html;
}
rtc_server {
enabled on;
listen 8000;
candidate 192.168.1.10;
}
vhost __defaultVhost__ {
hls {
enabled on;
hls_path ./objs/nginx/html;
hls_fragment 2;
hls_window 6;
}
http_remux {
enabled on;
}
rtc {
enabled on;
}
}
逐行解释一下关键的:
-
daemon off;很重要。Docker 容器的生命周期要求主进程在前台运行,如果 SRS 自己 daemon 化去后台,容器会直接退出。 -
log_tank console;前面说过,让日志走 stdout。 -
http_server里的 8080 是给播放端用的,dir指向 HLS 切片输出目录。 -
rtc_server里的candidate是 WebRTC 协商时告诉播放端的公网地址。如果填了内网 IP,公网播放端就永远连不上,这个后面细说。 -
hls_fragment 2表示每个切片两秒,hls_window 6保留最近 6 秒的窗口,配合低延迟直播体验会好一些。 -
http_remux负责把 RTMP 流转成 HTTP-FLV,浏览器端直接用 flv.js 就可以播放。
修改完配置后重启 SRS:
docker compose restart srs
再去查看日志确认模块都起来了,别只盯着容器状态。
4.3 公网 WebRTC 的候选地址问题
WebRTC 是 SRS 里最容易让人绕弯路的模块。RTMP 很简单,连上就行;WebRTC 需要 UDP 端口做音视频传输,同时要通过 ICE 机制协商候选地址,服务器必须告诉客户端自己真正可达的公网地址。
在 Docker bridge 网络下,SRS 看到的网卡 IP 是容器内部的虚拟 IP,把它作为 candidate 发给公网客户端,客户端自然连不上。解决办法有两个:
一种是把
rtc_server
里的 candidate 手动设成宿主机公网 IP:
rtc_server {
enabled on;
listen 8000;
candidate 203.0.113.10;
}
另一种是用 host 网络模式,让 SRS 直接看到宿主机网卡,SRS 会自动探测到公网 IP。这种方式省心,但端口暴露范围大,需要通过宿主机的安全组控制。
还有一个常见问题:WebRTC 使用的并不一定只是
listen
里声明的单个 UDP 端口,部分场景下 SRS 会为每个推流或拉流会话动态分配 UDP 端口,默认范围可能是
8000-8100
或者由配置决定。你要把整个 UDP 段在宿主机防火墙和安全组里放行,否则就会出现"端口 8000 明明开了,WebRTC 还是连不上"的情况。
个人经验是,单机部署 WebRTC,优先用 host 网络,然后明确告诉运维放行哪一个 UDP 范围,避免在 bridge 网络里折腾 candidate 映射。
4.4 HTTPS 和反向代理怎么配合
SRS 的 HTTP 服务默认是明文 HTTP,但是现在的浏览器有安全限制:在 HTTPS 页面里,很多能力对 HTTP 资源请求是不放行的,尤其是 WebRTC 播放,浏览器要求页面和信令都在安全上下文里。所以实际项目中,通常会在 SRS 前面放一层 Nginx 或 Caddy 做 HTTPS 终结。
反向代理的路径规划要注意:HLS 和 HTTP-FLV 走普通 HTTP 代理没问题,直接转发到 8080 端口;WebRTC 的 UDP 流量无法被 HTTP 反向代理转发,必须通过 SRS 自身暴露 UDP 端口。也就是说,HTTPS 证书是 SSL 层的事,UDP 音视频传输还是要单独放行。
我常用 Caddy 来做反向代理,配置极简:
live.example.com {
reverse_proxy localhost:8080
}
代理之后,播放地址变成:
https://live.example.com/live/demo.m3u8
浏览器页面如果是 HTTPS,播放这个地址就不会有 Mixed Content 拦截问题。
关于 SRS 本身的 HTTPS 能力,SRS 也支持直接配置 SSL 证书,但实际工程中我建议用独立反代来处,证书管理更灵活,SRS 会更专注做流媒体,职责分离。
5. 部署过程中的高发坑位:容器网络、资源限制和 Docker Desktop
5.1 Docker Desktop 的虚拟化和资源配额问题
在本地开发时,很多人第一站是 Windows 上的 Docker Desktop。安装后启动报错其实很常见,比如出现类似
virtualization support not detected
的提示。问题一般出在三个方向:
- 主板 BIOS 有没有开启虚拟化技术。Intel 的 VT-x 或 AMD 的 SVM 如果没有开启,Docker Desktop 的虚拟机根本起不来。
- Windows 功能里有没有启用 Hyper-V 和适用于 Linux 的 Windows 子系统(WSL2)。
- Docker Desktop 版本是否和当前系统版本匹配,旧版本在较新的 Windows 更新后可能出现兼容性问题。
我特别提醒一下资源配额:Docker Desktop 默认给 WSL2 虚拟机的内存不一定够用。如果你同时跑 SRS、数据库和前端开发工具,内存吃紧会导致 SRS 容器被 OOM 杀掉,表现就是容器状态显示 Exited 或者 Runing 但端口死活不通。
WSL2 的内存限额在
C:\Users\你的用户名\.wslconfig
里控制:
[wsl2]
memory=8GB
processors=4
改完要执行
wsl --shutdown
让配置生效。Mac 版则在 Docker Desktop 的 Settings 里调整 CPU 和内存。
5.2 端口被占用和防火墙导致的假死
启动 SRS 容器时如果报
port is already allocated
,不用看别的,就是宿主机某个端口已经被占用。先查是谁占的:
sudo lsof -i:1935
如果是自己机器上的服务占用了,可以直接换映射端口,比如
19350:1935
。注意换端口后,推流地址也要跟着换,不要只顾着改 Docker 配置。
还有一种更隐蔽的情况:容器是 Running 状态,但 RTMP 推流就是失败,报
connect failed
。这往往不是 SRS 的问题,而是宿主机防火墙没放行。检查一下:
sudo firewall-cmd --list-ports
如果没放行,执行:
sudo firewall-cmd --permanent --add-port=1935/tcp
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --permanent --add-port=1985/tcp
sudo firewall-cmd --permanent --add-port=8000/udp
sudo firewall-cmd --reload
这里要注意的是 TCP 和 UDP 是分开的,必须分别放行。WebRTC 走 UDP,很多人只放行了 TCP,结果就是 RTMP 正常、WebRTC 永远不通。
5.3 磁盘与日志:容器写爆存储的典型场景
流媒体服务最容易被忽视的就是磁盘增长问题。虽然 HLS 切片和 DVR 录制可以挂载到宿主机目录,但如果目录挂载没有做清理策略,时间长了会把磁盘写满,或者产生海量小文件。
HLS 的
hls_window
会控制 m3u8 保留的切片数量,正常情况下老的切片会被自动清理。但如果你开启了 DVR 录制,或 HLS 切片写入失败导致索引文件反复重建,目录下的
.ts
文件会越来越多。
我自己的处理方式是在宿主机上写一个定时清理任务,针对挂载出来的录制目录做保留周期策略,比如只保留最近 7 天。同时用
docker system df
查看镜像、容器、数据卷的磁盘占用,防止 Docker 本身的无用数据累积。
日志又是另一回事。如果没启用
log_tank console
,SRS 会往容器内的日志文件写内容,容器被删除时日志也没了,但容器运行期间文件会越写越大。如果你给 SRS 设置了重启策略,它频繁重启会把日志文件不断重建,底层存储很受伤。所以生产环境我坚持用 console 日志,让 Docker 引擎统一处理,再配合日志轮转,不会出现单个文件无限增长的问题。
5.4 快速判断问题出在容器层还是 SRS 层
排障时最怕在一个方向上死磕,我总结了一个简单的二分方法:
-
先确认能连通到端口。在宿主机上执行
curl http://localhost:1985/api/v1/streams,如果返回 JSON,说明 SRS API 正常,问题大概率在播放端或推流端。 -
如果 API 都不通,进入容器看 SRS 进程是否还在。执行
docker top srs,如果进程没了,说明 SRS 崩了,看docker logs srs。 -
如果进程在但 API 不通,很可能是端口映射或防火墙问题。执行
docker port srs看端口映射,再在宿主机上ss -lnup检查端口监听。
把这四个步骤走一遍,大部分部署问题都能定位到根因。不要把时间浪费在反复重启容器上,流媒体服务的问题通常是确定性的,找到是网络还是进程层面的问题,一个命令就能解决。
6. 进阶玩法:用 SRS 承载多种业务场景和鉴权
6.1 一份配置多路应用:直播、回放、低延迟流
SRS 的
vhost
机制很有意思,可以类比成 Nginx 的 server 块。同一个 SRS 服务里,可以配置多个虚拟主机,每个虚拟主机有独立的推拉流配置和协议开关。比如一个 vhost 负责低延迟 WebRTC 直播,另一个 vhost 负责普通的 HLS 回放,逻辑上互相隔离。
实际使用中,我通常会给不同的业务分配不同的应用名(就是推流地址里
live
这个位置),然后用应用名做路由和鉴权判断。推流地址
rtmp://domain/live1/stream
和
rtmp://domain/live2/stream
可以走同一个端口,SRS 内部根据应用名分发到不同处理逻辑。
这种方式的好处是不会为了多业务线起多个 SRS 容器,节省端口和管理成本,坏处是所有业务共享一个进程的 CPU 和内存,压测时需要留好余量。
6.2 on_publish 鉴权和防盗链
公网部署流媒体,最怕的就是任何人知道你的流地址后乱推流。SRS 提供 HTTP 回调机制,可以在推流开始前请求你自己的业务服务器做鉴权。
在 vhost 里加上:
vhost __defaultVhost__ {
http_hooks {
enabled on;
on_publish http://host.docker.internal:9000/api/v1/streams/auth;
}
}
这里
host.docker.internal
是容器内访问宿主机的地址,如果你的业务服务器跑在宿主机上可以用这个。如果是容器网络里的另一个服务,直接写服务名就行。
鉴权接口收到的是一个 POST 请求,包含了 app、stream、param 等字段,你的服务端逻辑校验后返回
0
表示允许,返回非 0 表示拒绝。我在实际项目中还会把推流端 IP 也带上,做 IP 黑名单和白名单控制,这个看具体业务需求。
注意这个回调是在推流开始前触发的,所以业务接口要保证足够快,建议超时时间不超过 3 秒,否则推流端一直等接口响应会误以为连不上。
6.3 监控与告警:读取 stats API
除了自动重启和日志收集,SRS 的 HTTP API 还提供了丰富的统计信息。我已经常用
/api/v1/streams
,它返回当前活跃流列表,包括流的码率、视频编码、推流时长等。
针对监控告警,我用得比较多的是轮询这些 API,然后把数据推到告警平台:
- 活跃流数量为 0,且业务上应该有流,触发断流告警。
- 活跃流数量异常上涨,可能是被恶意推流或异常业务流量,触发告警。
- CPU 和内存指标通过容器监控采集,比如用 Prometheus 配合 cAdvisor,告警规则里加一个“SRS 容器 CPU 超过 80%”的条件。
流媒体服务最怕的不是高负载,而是没有感知。断流、推流异常这类问题需要秒级发现,用 API 轮询加告警是成本最低的方案。
6.4 多实例与集群的前提认知
单个 SRS 实例能承载的并发是有限的,当业务量上来后,你可能会考虑多实例部署或集群。SRS 支持 origin/edge 架构,edge 节点负责分发拉流,origin 节点负责接收推流。用 Docker 部署时,每个节点也是一个容器,通过 Compose 在不同机器上拉起即可。
但我要泼一盆冷水:集群架构不是生产初期的第一优先级。如果你的单机并发还没到瓶颈,先别急着做集群,把单实例的监控、日志、鉴权做好,比什么都强。等业务真的到了要扩展的时候,再用 SRS 官方推荐的边缘集群方案,在 Docker 网络层把节点发现和容器调度规划好。
部署 SRS 这件事,最忌讳贪大求全。先把一路流推通、拉通,再一步步加协议、加鉴权、加监控,基础扎实之后,后面的扩展都会水到渠成。我在实际项目里走过很多弯路,回头来看,最大的收益都来自最基础的那几步踩明白了。
如果你准备在自己的机器上试,我建议就按第 3 节的最小实例开始,拿一个本地视频文件推一路流试试手,跑通之后再照着第 4 节的方法做生产配置。等真正上线过一两个业务,你就能体会到 SRS 配 Docker 这套组合拳有多省事了。
更多推荐

所有评论(0)