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个环节。你想想看,每个环节都可能成为瓶颈。

  1. 采集:摄像头、麦克风、屏幕捕获。这里容易出问题的是分辨率太高导致CPU飙升。
  2. 编码:H.264/H.265/AV1。编码器选软编还是硬编?软编质量好但吃CPU,硬编省资源但画质差一点。
  3. 封装:FLV/MP4/TS。封装格式影响首屏加载速度和seek性能。
  4. 传输:RTMP/WebRTC/SRT。网络抖动、丢包、带宽波动都在这里体现。
  5. 播放:解码 + 渲染。播放器兼容性、缓冲策略、音画同步。

我画了一张链路图,帮你直观理解:

推流链路全景图 采集 编码 封装 传输 播放 各环节常见瓶颈: • 采集:高分辨率(4K/8K)导致CPU过载,建议根据场景动态降级 • 编码:软编x264在1080p@60fps下单路占用约15-20% CPU核心 • 传输:TCP队头阻塞 + 丢包重传导致延迟雪崩 • 播放:解码器不兼容、缓冲策略不合理导致卡顿

一个小技巧:我在做链路优化时,习惯在每个环节打一个时间戳。比如采集完打一个,编码完打一个,传输前打一个。这样一旦出问题,我能立刻定位是哪个环节慢了。说白了,就是加监控。

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适合弱网。