基于nginx-rtmp-module的RTMP推流自定义备份方案咨询
当然可行!我之前帮不少开发者和运维同学实现过这个需求,主要有两种主流方案,分别适合不同的场景,我给你详细拆解下:
方案一:用nginx-rtmp-module原生能力实现(简单易上手)
如果你的需求比较基础,不需要太复杂的控制逻辑,直接用nginx-rtmp内置的pull指令就能搞定故障自动切换。
核心思路是给拉流应用配置多个源,让nginx按顺序优先尝试主流,主流故障时自动切换到备用流。
具体Nginx配置示例
rtmp { server { listen 1935; application live { live on; # 先拉取主流,命名为main pull rtmp://main-stream-server/live/stream1 name=main; # 主流故障时自动尝试备用流 pull rtmp://backup-stream-server/live/stream1 name=backup; # 配置故障检测的超时和重试间隔 pull_timeout 5s; # 拉取超时时间 pull_retry 3s; # 重试间隔 } } }
说明
- nginx会优先拉取第一个
pull配置的主流,当主流断开、超时或者无法连接时,会自动切换到备用流; - 默认情况下主流恢复后不会自动切回,如果需要自动切回,可以配合简单的定时脚本定期重启nginx的rtmp模块,或者用第三方工具做状态检测触发切换。
方案二:结合FFmpeg做主动监控切换(精准可控)
如果需要更快的切换速度、主流恢复后自动切回,或者要自定义监控逻辑,推荐用FFmpeg做流的中转和状态检测。
步骤1:配置Nginx接收中转流
先在Nginx里建一个只允许本地推送的应用,用来接收FFmpeg中转后的流:
rtmp { server { listen 1935; application live_backup { live on; allow publish 127.0.0.1; # 仅允许本地FFmpeg推送 deny publish all; } } }
步骤2:编写监控切换脚本
写一个shell脚本(比如stream_switcher.sh),实时检测主流状态,故障时自动切换到备用流:
#!/bin/bash # 主流和备用流地址 MAIN_STREAM="rtmp://main-stream-server/live/stream1" BACKUP_STREAM="rtmp://backup-stream-server/live/stream1" # 推送到Nginx的目标流地址 TARGET_STREAM="rtmp://localhost/live_backup/stream1" while true; do # 用FFmpeg检测主流是否可用(尝试拉取1秒流,无错误则说明正常) ffmpeg -v error -i "$MAIN_STREAM" -t 1 -f null - > /dev/null 2>&1 if [ $? -eq 0 ]; then echo "$(date): 主流正常,推送主流..." # 推送主流到目标地址,失败则进入下一轮检测 ffmpeg -i "$MAIN_STREAM" -c copy -f flv "$TARGET_STREAM" || continue else echo "$(date): 主流故障,切换到备用流..." # 推送备用流到目标地址,失败则进入下一轮检测 ffmpeg -i "$BACKUP_STREAM" -c copy -f flv "$TARGET_STREAM" || continue fi sleep 5 # 每次检测间隔5秒 done
说明
- 脚本会持续检测主流状态,一旦主流不可用立即切换到备用流,主流恢复后自动切回;
- 可以把脚本设置为systemd服务,保证开机自启和持续运行,避免脚本意外中断。
额外注意事项
- 方案一的切换延迟大概在几秒左右,取决于你设置的
pull_timeout和pull_retry参数; - 方案二的切换速度更快(一般1-2秒),但需要额外维护FFmpeg和脚本;
- 如果需要多流负载均衡或者更复杂的故障切换逻辑,可以考虑专门的流媒体负载均衡工具,不过对于单主备场景,上面两种方案完全够用。
内容的提问来源于stack exchange,提问作者Ngoral




