
我在一次大型电竞赛事直播中,遭遇了严重的并发冲击:突发百万人同时进入直播间,推流端响应卡顿、转码队列堆积,观众出现黑屏或延迟长达十几秒。尽管直播服务已部署在香港的数据中心,带宽与硬件资源充足,但瓶颈并不在物理设备,而是缺乏一套具备流量削峰和后端解耦能力的架构。最终,我们通过引入 LVS 四层负载、FFmpeg 异步推流转码、Redis 消息队列的组合方案,解决了并发下的吞吐与稳定性难题。
以下是我实战搭建这套架构的完整过程与技术细节。
一、架构概览:LVS + FFmpeg + Redis 削峰体系
整个直播推流架构包含三个核心组件:
- LVS(Linux Virtual Server):作为四层调度器,负责高并发连接的初步入口分发。
- FFmpeg + NGINX-RTMP:处理推流协议接入、转码、封装等任务。
- Redis 消息队列:用于缓存转码任务请求,实现异步削峰。
整体数据流程如下:
[主播客户端]
↓RTMP/RTSP/WebRTC推流
[LVS负载均衡]
↓
[多台NGINX-RTMP接入节点]
↓ 将流ID入列
[Redis Stream队列]
↓
[FFmpeg消费端集群]
↓
[HLS/FLV文件输出分发 → CDN边缘]
二、LVS 层设计:支撑百万连接的四层入口网关
1. LVS IPVS 配置
我们采用 LVS-DR 模式,利用内核层 IPVS 承接 RTMP/TCP 连接压力。其优势在于处理能力远高于传统 NGINX 七层代理。
# 安装依赖
apt install ipvsadm
# 启用 DR 模式虚拟服务
ipvsadm -A -t 123.123.123.123:1935 -s rr
ipvsadm -a -t 123.123.123.123:1935 -r 10.0.0.11:1935 -g
ipvsadm -a -t 123.123.123.123:1935 -r 10.0.0.12:1935 -g
2. 后端 Real Server 配置(回环绑定)
ifconfig lo:0 123.123.123.123 netmask 255.255.255.255 broadcast 123.123.123.123 up
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
通过 LVS 承接入口连接,我们成功把高并发请求压力从业务层剥离出来,前端节点只需专注处理具体流媒体协议。
三、NGINX-RTMP 推流接入:入列解耦,削峰入口
我们使用 NGINX-RTMP 模块仅做轻量接入,转码任务并不在该节点执行,而是推入 Redis Stream 消息队列,供后端转码器消费。
1. 推流接入配置
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
record off;
on_publish http://127.0.0.1:8080/api/on_publish;
}
}
}
2. 接入 API → Redis 入列
编写 Node.js 或 Python 接口,将推流元信息转入 Redis:
# on_publish 伪代码示例
import redis
import json
r = redis.Redis(host='localhost', port=6379)
def on_publish(stream_key):
task = {"stream_key": stream_key, "ts": time.time()}
r.xadd('ffmpeg:stream:queue', {'data': json.dumps(task)}, maxlen=10000)
这样,我们实现了“推流即入列”,前端节点不阻塞转码,完美隔离处理压力。
四、FFmpeg 后端集群:消费转码任务、异步输出
转码任务完全由后端消费器来异步处理,我们部署了若干台基于 FFmpeg 的容器,监听 Redis Stream 队列,分布式转码。
1. 消费逻辑
每个容器启动一个监听器脚本:
ffmpeg -i rtmp://origin/live/stream001 \
-c:v libx264 -b:v 2500k -c:a aac -f flv \
/var/hls/stream001.flv
我们使用 Supervisor + Redis Stream 控制消费并发,并监控状态。
2. Redis Stream 消费脚本片段
def consume_stream():
while True:
entries = r.xread({'ffmpeg:stream:queue': '0'}, block=0, count=1)
for stream in entries:
task = json.loads(stream[1][0][1][b'data'].decode())
process_ffmpeg(task["stream_key"])
3. CPU/GPU 分离策略(可选)
若推流量极高,可将节点按如下划分:
纯 CPU 节点:用于低码率转码。
NVIDIA GPU 节点:使用 h264_nvenc 加速高码率转码,支持并发数百路流处理。
五、稳定性保障与弹性优化
1. Redis 削峰策略
在 Redis Stream 中加入 TTL 机制与最大长度控制:
XADD ffmpeg:stream:queue MAXLEN 10000 ...
防止堆积引发 OOM。
2. 熔断机制
若消费失败,标记任务状态并推入延迟队列,避免转码失败引发重复爆炸。
3. 监控指标
- LVS:conn/s、drop/s;
- NGINX-RTMP:活跃连接、推流会话数;
- Redis:入队速度、滞留长度;
- FFmpeg:转码失败率、输出帧率。
通过 Grafana + Prometheus 可实现统一观测。
六、部署效果与实战数据
部署上线后,我们支撑了单场活动 超过120万并发推流连接:
- LVS 平均连接并发:95万+
- Redis 削峰能力:处理堆积高峰达 5000 req/s
- GPU 转码输出帧率:25fps * 320路 FFmpeg GPU 实例
- 系统稳定运行6小时无掉流、无重启。
传统直播架构在百万并发面前往往力不从心。通过构建 LVS 四层接入、Redis 削峰缓冲、FFmpeg 异步转码的组合体系,我们不仅将高并发流量解耦,还做到了流处理与资源调度的完全分离。这套方案在香港服务器的中转优势、出口带宽与本地 GPU 资源上,得到了最佳的实践落地。
这不是一套标准直播平台的解决方案,而是我在真实业务中构建的、面向高并发的推流削峰架构。希望对你有帮助。











