1. 推流基础与瓶颈分析
各位同学,咱们今天聊点实在的。推流这件事,说白了就是把摄像头采集的画面,经过编码、封装,然后通过网络送到服务器。听起来简单,对吧?但真正做高并发推流的时候,你会发现处处是坑。
我最早接触推流是在2015年,那时候做直播答题项目。嗯,就是那种几万人同时在线抢答的玩法。当时用的RTMP协议,服务器扛到5000路并发就开始疯狂丢帧。后来我才明白——不是服务器不行,是我根本没搞清楚瓶颈在哪。
这一章,咱们就把推流的底裤扒干净。从协议对比到链路拆解,再到CPU、内存、带宽、IO这些硬指标,一个一个说清楚。
1.1 三大推流协议对比:RTMP / WebRTC / SRT
先问个问题:你平时用什么协议推流?RTMP?WebRTC?还是SRT?
我见过不少团队,上来就选RTMP,理由是“大家都用”。但你要知道,RTMP是基于TCP的长连接协议,延迟天然高。而WebRTC走UDP,延迟低但抗丢包能力弱。SRT呢?它是在UDP上做了一层可靠传输,算是取了个折中。
咱们直接看对比表:
| 特性 | RTMP | WebRTC | SRT |
|---|---|---|---|
| 传输层 | TCP | UDP + DTLS/SRTP | UDP + 自定义ARQ |
| 典型延迟 | 3-6秒 | 200-500ms | 500ms-2秒 |
| 抗丢包 | 强(TCP重传) | 弱(依赖FEC) | 强(ARQ + FEC) |
| 并发成本 | 低(长连接复用) | 高(每个流独立端口) | 中(连接复用) |
| 适用场景 | 直播、点播 | 实时通话、低延迟互动 | 弱网环境、远距离传输 |
我的建议:如果你做的是秀场直播或游戏直播,RTMP够用。但如果你做的是在线教育或远程医疗,必须上WebRTC或SRT。我曾经在一个弱网项目中用RTMP,结果用户骂声一片——延迟太高,互动根本没法做。
1.2 推流链路拆解:从采集到播放
一条完整的推流链路,我习惯拆成5个环节。你想想看,每个环节都可能成为瓶颈。
- 采集:摄像头、麦克风、屏幕捕获。这里容易出问题的是分辨率太高导致CPU飙升。
- 编码:H.264/H.265/AV1。编码器选软编还是硬编?软编质量好但吃CPU,硬编省资源但画质差一点。
- 封装:FLV/MP4/TS。封装格式影响首屏加载速度和seek性能。
- 传输:RTMP/WebRTC/SRT。网络抖动、丢包、带宽波动都在这里体现。
- 播放:解码 + 渲染。播放器兼容性、缓冲策略、音画同步。
我画了一张链路图,帮你直观理解:
一个小技巧:我在做链路优化时,习惯在每个环节打一个时间戳。比如采集完打一个,编码完打一个,传输前打一个。这样一旦出问题,我能立刻定位是哪个环节慢了。说白了,就是加监控。
1.3 常见性能瓶颈:CPU / 内存 / 带宽 / IO
好,链路拆完了。咱们来看看具体哪些资源会成为瓶颈。我按优先级排个序:
1.3.1 CPU:最容易被忽视的杀手
CPU瓶颈主要来自编码。你想想看,一路1080p@60fps的H.264软编,x264的preset设为medium,单路就要吃掉一个物理核心的15-20%。如果服务器是32核,理论上能扛160路?别天真了——操作系统、网络IO、其他进程都要吃CPU。
我曾经在一个项目中,用Intel Xeon Gold 6248(20核40线程)做推流服务器。理论算力能扛300路,结果跑到180路就开始丢帧。后来一查,是x264的lookahead线程和主线程争抢L3缓存。解决办法?把preset降到veryfast,同时开启多线程编码。
注意:不要盲目相信CPU核心数。超线程(HT)在编码场景下只能带来10-15%的提升,远不如物理核心实在。我建议你按物理核心数的70%来估算并发上限。
1.3.2 内存:不只是容量问题
内存瓶颈分两块:容量和带宽。
- 容量:每路推流的内存占用大约在50-200MB(取决于GOP大小和缓存策略)。1000路就是50-200GB,听起来还好?但别忘了,操作系统、缓存、其他服务也要吃内存。
- 带宽:内存带宽才是隐藏的坑。DDR4-3200的理论带宽是25.6GB/s,但实际能跑到70%就不错了。如果编码器频繁拷贝帧数据,内存带宽会先于CPU成为瓶颈。
我建议你关注两个指标:vmstat 里的 bi/bo(块IO)和 sar -r 里的 kbmemused。如果内存带宽打满,考虑用内存池或零拷贝技术。
1.3.3 带宽:最贵的资源
带宽是钱堆出来的。一路1080p@4Mbps的推流,1000路就是4Gbps。国内BGP带宽的价格,你懂的。
但带宽瓶颈不只是钱的问题。TCP的拥塞控制算法在丢包时会主动降速,导致推流质量下降。我建议你考虑以下方案:
- 使用SRT或QUIC替代RTMP,减少TCP队头阻塞
- 开启FEC(前向纠错),减少重传
- 动态码率调整:根据网络状况自动降级
我的经验:在一个海外直播项目中,我们用SRT替代RTMP,在20%丢包率下依然能保持流畅推流。RTMP在同样条件下直接断流。所以,如果你面对的是弱网环境,别犹豫,上SRT。
1.3.4 IO:磁盘和网络的交织
IO瓶颈分磁盘IO和网络IO。
- 磁盘IO:如果你需要录制推流内容,磁盘写入会成为瓶颈。NVMe SSD的写入速度在3GB/s左右,但一路1080p@4Mbps的录制,1000路就是500MB/s。加上随机读写,实际能扛的并发更少。
- 网络IO:网卡中断处理、软中断、内存拷贝。万兆网卡在满负载下,软中断会吃掉一个CPU核心。我建议使用RSS(接收端缩放)和RPS(接收端包 steering)来分散中断负载。
这里有个配置示例,开启RSS:
# 查看网卡队列数
ethtool -l eth0
# 设置多队列
ethtool -L eth0 combined 8
# 绑定中断到不同CPU核心
echo 1 > /proc/irq/$(cat /sys/class/net/eth0/device/msi_irqs | head -1)/smp_affinity
echo 2 > /proc/irq/$(cat /sys/class/net/eth0/device/msi_irqs | tail -1)/smp_affinity
避坑指南:我曾经遇到过一个问题——磁盘IO没打满,但推流还是卡。后来发现是文件系统inode耗尽。录制文件太多,每个文件占一个inode,而ext4的inode数量是固定的。解决办法:换用XFS,或者定期清理旧文件。
1.4 本章小结
咱们这一章把推流的基础和瓶颈说透了。协议选型、链路拆解、资源瓶颈,每个点都是实战中踩过的坑。你记住一句话:没有万能的协议,只有合适的场景。RTMP适合稳定网络,WebRTC适合低延迟,SRT适合弱网。