ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Docker部署SRS流媒体服务器:从镜像到推拉流全指南

Docker部署SRS流媒体服务器:从镜像到推拉流全指南 SRSSimple Realtime Server是一款非常成熟的开源音视频流媒体服务器早期大家习惯把它叫做“简单的实时服务器”但实际上它在直播、低延迟通话、录播、SRT推流这些场景里表现相当能打。以往要跑一套流媒体服务从源码编译到依赖处理再折腾几个钟头是常有的事Docker 化之后流程被大幅压缩我今天就完整记录一下用 Docker 部署 SRS 的过程从镜像选择、容器配置到推拉流验证、常见坑位一次性写清楚。这篇内容适合正在选型流媒体服务、准备自建直播平台、或者在本地做音视频测试的同学。看完后不保证你能一步到位跑出商用级集群但至少从零开始搭一个稳定的 SRS 单节点验证 RTMP、HLS、WebRTC 这些核心协议链路是完全没有问题的。1. 项目背景与整体思路1.1 SRS 是什么为什么要自建流媒体服务SRS 全称 Simple Realtime Server底层使用 C 编写性能强悍单机并发能力相当可观。它支持 RTMP、HLS、DASH、WebRTC、SRT、GB28181 等多种协议无论你是做传统直播、低延迟互动还是接入监控摄像头流SRS 都能作为服务端核心来用。很多人纠结“直接用云厂商的 CDN 直播服务不好吗”这个取决于场景。云厂商的流媒体服务确实方便但如果你只是内部测试、临时做一场活动直播、或者在做产品原型验证按月付费的云直播产品往往显得冗余。自建 SRS 只要有一台普通服务器就能跑起完整的直播链路适合中小规模场景也能为后续上云迁移保留标准协议的灵活性。我最初用 SRS 是给一个在线教育产品做课堂直播的降级方案当时的核心需求是支持 RTMP 推流、H5 页面能看、同时还要控制延迟不能太高。SRS 的 HTTP-FLV 和 HLS 完美符合而且部署成本极低后面慢慢用它做各种流媒体实验发现它比很多商业产品的兼容性和灵活性都好。1.2 为什么选 Docker 而不是直接编译安装直接源码编译 SRS 不是不行官方文档也给了明确流程但问题出在依赖环境和版本管理上。SRS 涉及 openssl、ffmpeg、srt 等一堆库服务器上如果同时有别的业务很容易因为库版本冲突产生“站位错位”式的问题。编译一次加上下载依赖至少二十分钟如果想切换版本又要重新来一轮效率太低。Docker 的好处是把运行时环境、配置文件、依赖库整体封装在镜像里做到一次构建处处运行。升级回滚特别简单换镜像标签就能完成。SRS 官方长期维护 Docker 镜像跨版本升级成本几乎为零。对没有专职运维的团队来说Docker 部署能显著降低维护压力和出故障的概率。另外一个很重要的点是隔离性。流媒体服务对 TCP 连接数和网络带宽要求高通过 Docker 的端口映射和资源限制可以控制容器占用不至于某个异常流把整个服务器内存吃光。单容器崩溃也不会影响宿主机其他业务这个在混合部署的场景里非常实用。2. 环境准备与镜像获取2.1 Docker 环境安装要点先确认服务器上已经存在 Docker。使用docker -v检查版本如果还没有安装可以参考 Docker 官方脚本在 Ubuntu/Debian 系系统里执行curl -fsSL https://get.docker.com | bash systemctl enable --now docker在 CentOS/RHEL 系可以改用 yum 安装yum install -y yum-utils后配置官方仓库再装 docker-ce。Windows/macOS 用户建议直接安装 Docker Desktop不过生产环境还是以 Linux 为主。创建容器之前建议先确认内核参数开启 IPv4 转发SRS 的 WebRTC 场景对网络栈依赖比较重sysctl -w net.ipv4.ip_forward1 echo net.ipv4.ip_forward1 /etc/sysctl.conf注意如果服务器本身有防火墙提前放行 TCP 1935、1985、8080 以及 UDP 8000 端口。WebRTC 走的是 UDP 传输只放 TCP 会导致连接一直建立不起来。2.2 拉取 SRS 官方镜像SRS 官方镜像发布在 Docker Hub 和阿里云镜像仓库推荐优先使用阿里云镜像地址在国内拉取速度快得多docker pull registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5这个5是主版本号对应 SRS 5.x。如果网络环境特殊使用 Docker Hub 也可以docker pull ossrs/srs:5拉取完成后执行docker images能看到镜像列表。官方镜像默认工作目录/usr/local/srs里面包含 srs 主程序、配置文件模板和全套支持工具。观察容器内文件结构有助于理解 SRS 的行为方式建议先用交互式命令进去逛一圈docker run -it --rm registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5 bash ls /usr/local/srs/conf/这样做的目的是熟悉配置文件和目录布局。conf/下放着docker.conf、rtmp.conf、hls.conf、webrtc.conf等预置模板直接拿模板做修改比从空文件开始手写配置更稳妥。3. SRS 容器部署实操3.1 最简方式先跑起来使用官方默认配置直接启动验证 SRS 能正常工作。第一条命令只映射必要的端口适合首次快速验证docker run -d --name srs \ -p 1935:1935 \ -p 1985:1985 \ -p 8080:8080 \ registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5各端口作用解释一下1935是 RTMP 协议默认端口用于推流和拉流1985是 SRS HTTP API 端口提供流状态查询、在线统计等功能8080用于 HTTP 服务包含 HLS 播放地址访问和 SRS 控制台。启动后访问http://服务器IP:8080/console/可以看到 SRS 内置的 Web 控制台。页面能显示当前流数、客户端数、CPU 占用等运行状态这个控制台虽然在生产环境用处不大但调试阶段相当好用可以直观确认服务是否活着。如果页面能打开说明基础服务已正常。这时候只是用了最小化配置离“能推能拉”还有一步。要支持完整的协议功能需要引入更详细的配置文件。3.2 自定义配置文件挂载最小配置只能跑 RTMP 相关的简单功能生产环境需要在配置文件里明确 HLS 开关、HTTP 回调、鉴权策略、SRT 支持等。SRS 的优势在于所有功能都是配置驱动的改配置文件后重启容器即可。在宿主机创建配置目录准备持久化配置文件mkdir -p /opt/srs/conf /opt/srs/objs touch /opt/srs/conf/srs.conf chmod 755 /opt/srs/conf/srs.conf配置文件格式如下兼容 SRS 5.x 的常见使用需求listen 1935; max_connections 1000; daemon off; srs_log_tank console; http_api { enabled on; listen 1985; } http_server { enabled on; listen 8080; dir ./objs/nginx/html; } rtc_server { enabled on; listen 8000; candidate $CANDIDATE; } vhost __defaultVhost__ { hls { enabled on; hls_path ./objs/nginx/html; hls_fragment 2; hls_window 12; } http_remux { enabled on; mount [vhost]/[app]/[stream].flv; } srt { enabled on; srt_latency 300; } }需要注意daemon off配合srs_log_tank console是关键Docker 容器里如果以 daemon 方式运行进程会脱离 PID 1 导致容器退出。日志打到 stdout 后可以通过docker logs srs实时查看排查问题效率高。candidate $CANDIDATE是 WebRTC 必须的配置项稍后启动容器时要通过环境变量传入服务器的公网 IP 或内网 IP。WebRTC 协商过程需要告诉客户端“我应该连哪个 IP”这个 IP 配不对即使端口全开也无法通话。3.3 启动带配置的 SRS 容器确认配置文件无误后开始启动正式容器docker run -d --name srs \ -p 1935:1935 \ -p 1985:1985 \ -p 8080:8080 \ -p 8000:8000/udp \ -p 10080:10080/udp \ -e CANDIDATE你的服务器公网IP \ -v /opt/srs/conf/srs.conf:/usr/local/srs/conf/srs.conf:ro \ -v /opt/srs/objs:/usr/local/srs/objs \ registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5 \ ./objs/srs -c conf/srs.conf映射 UDP 8000 端口给 WebRTC映射 10080 给 SRT。-v /opt/srs/objs这个目录映射很关键HLS 分片文件、DVR 录像、HTTP 服务目录全在这里不挂载出来的话容器一删数据就全没了。./objs/srs -c conf/srs.conf是覆盖默认启动命令官方镜像的默认入口本身就会加载配置但显式指定配置文件可以避免误用到容器内部的预置模板。启动后使用docker logs srs观察日志看到类似下面内容就代表启动成功SRS 5.0.xxx Copyright ... config: conf/srs.conf startup: ...3.4 配置持久化与后续维护容器跑起来以后日常维护主要围绕修改配置和数据备份展开。每次逻辑调整只需要在宿主机编辑/opt/srs/conf/srs.conf然后重启容器docker restart srs重启操作很快SRS 进程从加载配置到监听端口就绪一般只需要几秒。数据备份就更简单了把/opt/srs/objs目录整体打包即可HLS 切片、录像文件全部在里面。这里谈一下为什么不推荐使用 Docker Desktop 跑生产环境的 SRS。Docker Desktop 在 Windows/macOS 上底层依赖虚拟化技术网络模型和 Linux 原生环境差异明显特别是 UDP 端口映射和 NAT 穿透行为不稳定做本地开发测试问题不大但压测和生产建议还是用 Linux 服务器可以少踩很多怪坑。4. 推拉流验证与协议实战4.1 RTMP 直播推拉流全流程SRS 部署完成后第一个标准动作是用 RTMP 做推拉流验证。使用 ffmpeg 推送本地视频文件或者摄像头流ffmpeg -re -i test.mp4 -c copy -f flv rtmp://服务器IP/live/test如果没有现成的视频可以用 SRS 自带的 FFmpeg 工具生成测试视频源或者简单用手机摄像头推流。SRS 默认应用名是livetest是自定义流名称后续拉流时保持同一路径即可。RTMP 拉流用以下命令ffplay rtmp://服务器IP/live/test也可以使用 VLC 播放器打开网络串流输入同样的 RTMP 地址。此时去 SRS 控制台http://服务器IP:8080/console/里面能够看到活跃流列表里面记录着推流时间、码率、帧率、客户端数量。这组命令看似简单却是验证整套链路是否通畅的黄金路径。实际操作中会遇到一个情况推流端的-re参数如果漏了ffmpeg 会以极限速度把文件瞬间推完直播画面一眨眼就结束了。第一次做测试时我也踩过这个坑原因是-re强制 ffmpeg 按原始帧率读取文件模拟实时流不加就会以最快速度推流。4.2 基于 HLS 的播放验证HLS 的验证重点在 HTTP 服务是否正常响应。推流后等待 2-3 秒SRS 的 HLS 模块会把直播流转为 TS 分片文件播放地址通常是http://服务器IP:8080/live/test.m3u8在浏览器里访问这个地址或者用 VLC 打开 m3u8 链接能看到画面就说明 HLS 链路正常。m3u8 索引文件里记录了分片组成的序列每个分片包含约 2 秒的视频数据具体分片时长由hls_fragment和hls_window控制。hls_fragment 2表示每 2 秒生成一个 TS 文件hls_window 12表示索引里只保留最近 12 秒的分片。HLS 延迟基本在 6-10 秒之间这是因为播放器需要先缓冲几个分片才能保证播放连续。如果对延迟要求高HTTP-FLV 才是更优解。SRS 配置里已经开了http_remux可以直接用 FLV 地址播放http://服务器IP:8080/live/test.flvFLV 播放的延迟通常在 1-3 秒很多在线课堂、低延迟直播场景都用这个模式。支持 FLV 的播放器非常多小程序、Web 端、移动端都有成熟 SDK 可用。4.3 WebRTC 低延迟验证WebRTC 的验证相对复杂一些但对低延迟互动场景必不可少。SRS 5.x 对 WebRTC 协议支持已经很成熟推拉流都是标准接口。在浏览器里打开 SRS 提供的 WebRTC 测试页面http://服务器IP:8080/players/rtc_player.html如果使用虚拟摄像头或桌面共享推流也可以使用 SRS 的 WebRTC 推流页面。重点考验的是之前配置的candidate $CANDIDATE是否设置正确。这个参数决定了 SDP 协商时向客户端公布的 IP 地址。我在用云服务器测试 WebRTC 时遇到过一种典型问题服务器有公网 IP 也有内网 IP没有显式设置 candidate 时SRS 可能把内网 IP 写入 SDP浏览器拿它去连接结果一直卡在“连接中”状态。解决办法很直接在启动命令的环境变量里把CANDIDATE设为该服务器的公网 IP或者内网测试环境就设内网 IP。也可以通过配置文件硬编码rtc_server { enabled on; listen 8000; candidate 你的IP; }DNS-DERP 之类的生产级中继方案属于进阶话题单机测试阶段设置 candidate 足够用。WebRTC 跑通后延迟基本能做到 500ms 以内是当前公共互联网上体验最好的低延迟方案之一。4.4 SRT 弱网传输验证SRT 协议主要用于弱网环境下的稳定传输SRS 5.x 内置了 SRT 支持。rtmp 推流之外可以用 ffmpeg 以 SRT 方式推流ffmpeg -re -i test.mp4 -c copy -f mpegts srt://服务器IP:10080?streamid#!::rlive/test,mpublish拉流时把mpublish改成mrequest即可。SRT 的优点是自带重传机制在网络抖动时可以保持视频流稳定很多广电级传输场景都在使用。SRS 的 SRT 支持在实际测试中表现不错配置不算复杂但要求客户端使用支持 SRT 的 ffmpeg 或专用推流端。5. 常见问题排查与生产优化5.1 端口冲突与拉流失败最常发生的问题是端口被占用尤其是 1935 端口如果服务器之前跑过其他流媒体服务很容易出现“RTMP 推流失败”的情况。排查命令netstat -tlnp | grep 1935 ss -lunp | grep 8000如果有其他进程占用杀掉冲突进程或修改 SRS 配置的监听端口都可以。拉流失败另一个常见原因是从公网拉流时防火墙没有放行对应端口这个前面环境准备时提过需要系统防火墙和安全组两端都检查一遍。经验教训使用云服务器时安全组策略和系统防火墙是两个独立维度只放行安全组而系统防火墙默认 deny 的情况下外网依然连不进去。5.2 HTTP API 统计与流状态排查SRS 的 HTTP 服务提供了多种 API 接口。查询当前活跃流数量和客户端信息curl http://服务器IP:1985/api/v1/streams/返回的是 JSON 结构里面包含每个流的 ID、名字、来源 IP、推流时间、视频编码、音频编码、码率等详细信息。这个接口在定位“为什么流黑屏”“为什么播放卡顿”时非常有用可以判断推流端到底有没有成功推上来以及编码参数是否异常。还有几个常用接口/api/v1/clients/查看当前所有客户端连接信息/api/v1/raw/streams/可获取更底层的流状态/api/v1/record查询 DVR 录制信息。用这些 API 可以封装出简单的流监控脚本定时探测流是否在线断了就告警。我在维护 SRS 期间就是靠这些接口做了个轻量级看板配合告警规则能及时感知异常流。5.3 控制台进不去和鉴权问题浏览器访问控制台提示 404 或者无法加载多数情况是 HTTP 服务根目录配置不对。配置文件里的dir ./objs/nginx/html路径需要和宿主机挂载的目录对应。如果镜像内该路径下不存在console目录就需要在配置中明确指定。生产环境中 SRS 控制台和 API 不应直接暴露在公网建议用反向代理配合鉴权。简单做法是在 Nginx 里给/console/和/api/加 basic auth或者限制来源 IP。SRS 自身也支持 HTTP 回调鉴权推流时向鉴权服务发请求鉴权失败拒绝推流。回调配置在 vhost 下http_hooks { on_publish http://你的鉴权服务/api/auth_publish; }这层设计能有效防止陌生人往你的流媒体服务器推流对外提供服务时必须考虑。5.4 容器内存和 CPU 资源控制流媒体服务对资源消耗十分敏感尤其是码率高的流。Docker 直接启动时不加限制会占满宿主机资源建议根据业务预估给容器加上资源配额docker run -d --name srs \ --memory1g \ --cpus1.5 \ ... \ registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5 \ ./objs/srs -c conf/srs.confSRS 本身性能很好单核处理多路标清流没有压力但高码率流和大量并发客户端会有明显 CPU 消耗。加资源限制的另一个好处是防止异常流量把容器 CPU 打满拖垮宿主机上的其他服务。5.5 日志切割与长期运维SRS 把日志打到 stdout 后全部交给 Docker 的 logging driver 管理。生产环境建议配置json-file日志轮转docker run -d --name srs \ --log-opt max-size50m \ --log-opt max-file5 \ ... \ registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5max-size50m表示每个日志文件最大 50MBmax-file5表示保留 5 个历史文件。如果不加这个配置长时间运行后/var/lib/docker/containers/目录会被日志撑爆清理起来很头疼。5.6 版本升级与回滚策略Docker 部署升级流程极其简单。先拉取新镜像docker pull registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5然后删除旧容器重新运行。配置文件和数据目录都在宿主机上容器删除重建不影响业务数据。升级前最好先备份当前配置文件和 objs 目录以防万一需要回滚cp -r /opt/srs/conf /opt/srs/conf.bak.$(date %Y%m%d) cp -r /opt/srs/objs /opt/srs/objs.bak.$(date %Y%m%d)SRS 5.x 各小版本之间配置兼容性比较好但大版本之间有一定差异如果跨大版本升级需要仔细阅读官方迁移文档。6. 进阶玩法与扩展场景6.1 FFmpeg 转码集成SRS 本身是一个流媒体服务器不包含转码能力。接入不同编码源的流时需要配合 FFmpeg 做转码。例如 RTMP 推流编码是 H.264AAC移动端播放基本够用但如果要兼容老旧设备或者统一码率就需要转码。常见的做法是在宿主机部署 FFmpeg把源流转成不同清晰度的目标流后再推给 SRS。也可以用 FFmpeg 做截图、水印、多画面合成等处理这些都不需要 SRS 参与属于流媒体链路的前处理或后处理环节。6.2 负载均衡与集群部署单节点 SRS 最多能支撑的并发量受限于服务器本身的 CPU、带宽和内存。有更高的承载需求时可以用 SRS 的 Origin 和 Edge 模式做集群。Origin 作为源站接收推流Edge 节点负责对外分发。SRS 的原生集群配置比很多商业流媒体服务简单得多基本逻辑是 Edge 回源自 Origin 拉流Origin 只需要正常配置推流域名和拉流域名解析Edge 上开启回源配置即可。这个模式能横向扩展播放能力而推流能力和存储能力仍然集中在 Origin。我见过不少团队用云厂商的负载均衡器配合多台 SRS Edge 节点搭建分发网络在区域间有多点部署需求时非常有效。对于单数据中心几千路并发以内的场景单机 SRS 加合理调优通常足以应对不必一开始就上集群。6.3 录制回放与 DVRSRS 支持将直播流录制为 MP4 文件。配置里开启 DVR 模块后推流期间会自动生成录像文件结束后可直接用于点播回放vhost __defaultVhost__ { dvr { enabled on; dvr_path ./objs/nginx/html/[app]/[stream].[timestamp].mp4; dvr_plan session; } }dvr_plan session表示每次推流会话生成一个 MP4 文件配合 HTTP 目录可以直接提供回看地址。录制文件同样存储在/opt/srs/objs目录下通过挂载目录可以方便地迁移和备份。6.4 鉴权与防盗链配置对外提供流媒体服务时防盗链是必修课。SRS 支持 referer 防盗链和 token 鉴权。referer 方法适合防止网页端盗播token 方法则更适合 App 场景。token 鉴权通常在推流环节用 HTTP 回调实现播放环节用 referer 或者自定义头。SRS 也支持内置的on_connect、on_play等回调可以在播放前请求业务服务校验权限。相比完全开放的服务加一层鉴权能大幅减少被别人盗用带宽的可能。6.5 与 WebRTC 通话、直播结合SRS 在 5.x 版本把 WebRTC 作为一等公民支持可以实现直播与实时通话的混合场景。例如观众通过 WebRTC 上麦连麦服务端将多路流合流转成直播流再分发给所有观众。这种场景常见于在线课堂、连麦直播、视频面试等。SRS 提供的 SFU 能力虽然不如专业集成的音视频通信云方便但对于已经具备一定音视频经验的研发团队完全可以基于 SRS 搭建一套可控的私有低延迟互动系统。整体成本比云厂商的实时音视频服务低很多只是需要自己处理客户端 SDK 和信令服务。我在实际使用中发现SRS 最核心的竞争力不只是功能多而是配置改动后的行为可预测性很强几乎每个模块都有详细的日志输出出了任何问题都能顺着日志找到根因。排查问题思路基本是三步确认网络通不通、确认配置对不对、确认日志有没有报错。把这条路走通SRS 的日常维护不会占用太多精力。最后再分享一个小技巧在测试 WebRTC 或排查推拉流问题时尽量使用 SRS 自带的控制台页面和示例播放器它们能省去你自行判断播放器兼容性的时间。遇到问题不要急着改配置先看日志里的错误关键字按模块去定位比自己瞎猜快得多。这套基于 Docker 的部署方式我已经稳定运行很长时间希望这篇记录能帮你在流媒体服务搭建上少走弯路。
返回列表