资讯详情

资讯详情

告别直播卡顿:丢包原因排查与推流端优化方案

做直播技术这几年被问得最多的一个问题是画面为什么又卡了然后甩过来一张网络截图丢包率2%——外行人看这是个小数但经历过的人都知道直播场景里2%的丢包基本等于灾难画面瞬间马赛克、声音断断续续、弹幕都跟着掉线主播这边看着一切正常观众那端已经骂声一片。如何避免直播丢包是个老话题但很多朋友的理解还停留在换个好路由器或者加大带宽这种表面操作上。丢包是结果不是原因。光盯着结果使力往往钱花了、设备升级了关键时刻照样卡。这篇内容我会从丢包的成因链路说起把推流端、传输协议、接收端、网络侧这四层常见的丢包场景都拆开结合我这些年实际排障的经验给出一套可以直接落地的优化方案。1. 直播丢包为什么比想象中更致命——先看现象再谈对策很多人对丢包的认知来自文件下载或者网页浏览丢一个包大不了TCP重传一下页面慢个零点几秒人根本感知不到。但直播是完全不同的逻辑。直播走的是实时传输通道以UDP类协议为主。它没有文件传输里那种完整的数据重传机制——因为视频帧是实时产生的错过了播放时间点这个包就算到了也没有意义。你可以把直播数据流想象成一条流水线传送带上的零件每个零件都要在特定时刻装上机器。传送带半路掉了一个零件机器不会停下来等你捡回来而是跳过这个零件继续运转。对观众来说体现出来的就是那一瞬间画面碎了、声音断了。丢包率对直播体验的影响不是线性的而是跳跃式的。丢包率范围对直播体验的实际影响0% - 0.1%几乎无感知画面通常稳定0.1% - 0.5%偶发轻微卡顿部分设备可被解码器掩盖0.5% - 1%开始出现可感知的画面破损音频偶发断续1% - 3%明显卡顿、花屏互动频繁时体验急剧恶化3% - 5%直播基本不可看声音和画面频繁中断5%以上连接中断风险极高推流可能直接被服务端断开我见过最典型的案例是某虚拟主播团队上行丢包率只有0.8%但观众反馈卡得没法看。排查之后发现他们的丢包集中在每秒钟画面切换最剧烈的瞬间——也就是最高码率的I帧位置。丢包对直播的伤害还挑时机如果丢的是I帧关键帧接收端可能直接卡几秒等待下一个I帧如果丢的是P帧画面就出现局部马赛克和撕裂。所以搞直播技术的朋友要建立的第一认知是丢包率不是绝对值越低越好而是要在关键帧、峰值码率这些脆弱时刻保证不丢包。这个前提直接决定了下面每一步优化策略的方向。2. 数据包在哪一层丢的四种最常见的丢包成因要避免丢包先得搞清楚包是怎么丢的。我排障时习惯把丢包链路分成四个层级每一层的丢包特征都不同排查手段也完全不一样。2.1 物理传输层Wi-Fi信号和网线是最常见的黑洞无线网络是丢包的重灾区。Wi-Fi本质上是半双工通信同一时间只有一个设备能占用无线信道发送数据。如果直播设备手机、笔记本电脑和路由器之间隔着墙或者周围有大量其他Wi-Fi网络在抢信道数据帧就会在无线空口处反复碰撞、退避、最终被丢弃。这里有个容易被忽略的细节接收信号强度不等于链路质量。很多手机显示Wi-Fi信号是满格但实际协商速率可能因为干扰已经跌到几十兆比特每秒。当推流码率达到8Mbps时这几十Mbps的协商速率里还要扣除无线传输的碰撞损耗、帧间隔开销有效吞吐可能只剩下几Mbps丢包自然就来了。有线网络相对更稳定但也不是绝对安全老旧网线五类线在长距离传输时信号衰减明显水晶头接触不良会导致大量CRC错误帧。我排查过一个问题主播端换了根看似没问题的网线丢包就消失了——旧网线的其中一对线接触不良数据传输时好时坏ping网关却看不出明显波动。2.2 网络拥塞层上行带宽被打满后路由器开始扔包这种丢包在主播端极其常见。家用宽带的上行带宽和下行带宽是不对等的很多所谓千兆宽带上行只有30-50Mbps。开直播的同时还在上传视频素材、挂网盘同步、开视频会议——上行带宽瞬间被打满。路由器内置的缓冲队列是有限的数据堆积到队列溢出之后新来的包只能直接丢弃。这个道理就像只有一个入口的停车场车开进来的速度超过了出场速度入口就会堵死后面的车根本进不来只能绕路去别的停车场丢包或者重新连接。我自己做过一个测试在20Mbps上行带宽的线路上用8Mbps码率推流的同时再开一个网盘批量上传丢包率立刻从0%飙到2%以上。直播期间上行带宽的占用率必须控制在80%以内你永远猜不到操作系统在后台会偷偷跑什么流量。2.3 路由与转发层家用路由器芯片能力的隐性瓶颈很多主播用的还是运营商送的基础款路由器表面参数看着不错但实际转发能力很有限。当连接数达到几千条、NAT会话表接近填满时路由器CPU占用率飙升转发延迟和丢包率同时上升。这种情况在多人共用网络比如主播开了个小型共播间的时候尤为明显。特征很典型局域网内部ping一切正常但ping外网IP地址时丢包率随着时间推移慢慢上涨。这时把路由器重启一下会暂时恢复但过几小时又会复发——根源是路由器的NAT会话表老化机制不健全大量半开连接占据了资源。2.4 骨干网与CDN层你管得了家里的设备管不了中间的链路从主播家里到直播平台的服务端数据要经过运营商骨干网、区域网络节点、CDN边缘节点等多段链路。任何一段出现拥塞、线路劣化、路由绕路都会造成丢包。这种丢包的表现是主播本地测一切正常但推流到远端测试服务器时丢包明显。这里最容易踩的坑是把锅全甩给自家网络。判断方法很简单分别测试到多个不同节点的丢包情况如果只有特定节点的丢包率高说明问题出在中间链路如果所有节点都丢包才需要怀疑本地网络。3. 动手排查前先学会测准丢包别把噪声当故障很多人一听说丢包就开始盲目调参数、换硬件结果越调越差。我建议先花半小时做一轮准确的测量搞清楚三个数字丢包率、丢包分布、丢包位置。3.1 ping能测出什么、测不出什么ping是最基础的工具但它的结论很有限。用ping去测直播丢包有一个致命缺陷默认情况下ping发的是32字节的小包这种小包在网络转发时几乎不会触发分片、排队等机制即使链路质量已经很差小包的丢包率依然可能接近0%。但直播的包通常是每个超过1000字节的大包TS流打包后往往接近MTU上限大包对链路质量更敏感转发设备队列更深、更易触发拥塞丢弃。所以要用接近实际业务包大小的数据包去测才有参考意义。正确姿势是用ping -s参数指定大小比如发1200字节的包测300次看丢包率和延迟抖动ping -s 1200 -c 300 目标IP地址3.2 用UDP流量做模拟推流测试比ping更接近实际的是直接用UDP流去压测链路。这里推荐perf3这类工具可以模拟出和直播推流类似的恒定码流。操作思路如下在远端云主机上启动iperf3的服务端在本地主播电脑上启动客户端以10Mbps的恒定速率打UDP流持续5分钟。# 服务端远端云主机 iperf3 -s # 客户端本地主播电脑 iperf3 -c 远端IP -u -b 10M -t 300跑完之后会输出一个汇总重点关注jitter抖动和lost/Total丢包率这两项。如果这个测试丢包率在0.05%以内说明本地到远端的原始链路是健康的问题大概率出在编码端或协议层如果丢包率超过0.5%网络侧确实需要治理。注意实测时机的选择很重要。建议分别在网络忙时晚上八九点和闲时凌晨各测一轮对比这组数据能帮你区分是拥塞型丢包还是结构性丢包。3.3 从推流日志中读丢包指标无论用ffmpeg还是其他推流工具日志里通常会输出实时网络统计。以ffmpeg推RTMP为例跑的报错里会频繁出现类似NACK或retry的字样。NACK是接收方向发送方请求重传的指令出现NACK说明有数据包在路上丢了、或者迟到被判定为丢失。更专业的做法是抓包分析。用Wireshark设置过滤器只采集推流目的端口的数据包然后统计TCP重传数如果是TCP协议或RTCP的Receiver Report里的丢包计数。我习惯把推流过程录包30秒重点看有没有尖峰型丢包——也就是某个瞬间丢了几百个包、然后又恢复正常。尖峰型丢包通常是网络瞬断或路由收敛造成的和持续平稳丢包的治理思路完全不同。4. 推流端优化编码参数和传输协议怎么选网络不是完全可控的但推流端可以做很多未雨绸缪的工作把丢包的破坏力降到最低。4.1 码率、分辨率和GOP的匹配关系码率设置不是越高越好。码率越接近带宽上限越容易触发拥塞丢包。我的经验是推流码率控制在实测上行带宽的60%-70%比较安全。比如上行带宽测量值是15Mbps那码率就取8-10Mbps留出足够余量给TCP确认包、控制信令和突发流量。分辨率和帧率影响的是单帧的数据量。1080p60的直播每一帧的数据量比1080p30的还大I帧更是可能达到几百KB。这些大帧在传输时会被分片成多个IP包任何一个分片丢失都会导致整个帧无法解码。降低帧率到50FPS甚至30FPS虽然观感上略平滑度下降但能显著降低峰值码率提升抗丢包能力。GOP关键帧间隔同样关键。GOP越长两个I帧之间的P帧越多一旦丢包累计误差就越严重。通用直播场景建议把GOP设置为2秒即帧率的2倍60FPS下为120。这个周期兼顾了画质和恢复速度——丢包后最多2秒就能等到下一个关键帧恢复画面。参数保守设置激进设置适用场景视频编码H.264H.265/AV1H.264兼容性最好解码器抗丢包错误隐藏算法成熟码率上行带宽的60%上行带宽的85%网络波动大的场景使用保守值帧率30FPS60FPS运动剧烈的场景游戏直播才值得上60FPSGOP2秒4秒越短恢复越快但同码率下画质略降音频码率128kbps AAC192kbps AAC音频丢包比视频丢包更难容忍优先保证音频码率不过高4.2 传输协议的抗丢包能力对比推流协议的选择直接决定了丢包后的行为模式。我把常见协议做了个对比协议传输层抗丢包机制适用场景RTMPTCP依赖TCP重传延迟较高丢包引发队头阻塞传统直播推流兼容性好但抗丢包最弱SRTUDP内置ARQ重传和FEC前向纠错针对性极强公共互联网环境下的高质量推流首选WebRTCUDPFECARQ抖动缓冲三件套延迟极低连麦、互动直播、低延迟场景QUICUDP基于UDP的可靠传输避免队头阻塞拉流端非推流端逐渐普及这里重点说SRT。它专为不可控的公共互联网视频传输设计支持在丢包率高达20%的环境里仍然保持画面可用。它在发送端根据网络状况动态调整FEC冗余比例发现丢包就启动ARQ重传还会自动调整发送速率——这种自适应拥塞控制机制在RTMP里完全没有。现在很多直播平台已经支持SRT推流如果你的场景对延迟要求不极端允许1秒左右从RTMP换到SRT是最立竿见影的优化。4.3 FEC和ARQ的取舍逻辑前向纠错FEC和自动重传ARQ是种子握手的两个反方向。FEC是在发送的数据包里加入冗余包即便丢掉一部分也能由冗余数据还原出原始数据代价是增加带宽消耗ARQ是发现丢包后请求发送方重发代价是增加延迟。实践中很少只用一个。纯FEC在丢包率高于冗余比例时照样失效纯ARQ在实时直播里会导致延迟越来越大。SRT的聪明之处在于动态融合丢包率低时FEC冗余比例自动降低丢包率升高时提高FEC比例并启用ARQ兜底。WebRTC的NACKFEC机制也是类似逻辑。对于普通主播我的建议是优先选带FEC的协议SRT或WebRTC不要把宝压在语音级重传上。因为直播是单向的重传带来的延迟增加对观众体验的伤害甚至比丢包本身更大。5. 接收端兜底策略用迟到的补偿弥合丢包损伤推流端做得再好传输链路偶尔丢包还是无法完全避免。接收端的策略决定了这些偶发丢包最终会不会被观众看到。5.1 抖动缓冲Jitter Buffer给迟到包一个缓刑期抖动缓冲是所有播放器和接收端必备的组件。它不直接防止丢包而是把收到的数据包先囤积一段时间再按序播放。这样如果一个包在路上延迟了50ms只要没超过缓冲区的等待时间它依然能赶上播放。缓冲时长是个双刃剑缓冲越长抗抖动和抗迟到能力越强但延迟也越高。看体育直播、弹幕互动多的场景缓冲超过3秒观众就受不了看一般的内容直播缓冲设在5秒以上也没问题。更专业的做法是自适应抖动缓冲网络好时缓冲自动缩小到几百毫秒网络恶化时缓冲自动拉长。WebRTC实现了这种机制效果显著——实测在网络丢包率2%且有明显抖动的情况下自适应缓冲可以让观众侧感知到的卡顿减少一半以上。5.2 解码器错误隐藏把花屏变成微糊当丢包确实发生了、帧也不完整了解码器还有最后一道防线错误隐藏Error Concealment。原理是对于丢失的宏块用前一个帧的对应位置数据来填补或者用周围宏块插值预测。H.264/H.265解码器基本都有这个能力但效果取决于编码器的容错选项。在使用x264编码时开启Slice切片将帧分成多个独立切片每个切片可独立解码能显著降低单包丢失的破坏半径。FMO灵活宏块排序技术也是类似思路但兼容性较差实际部署不多。对普通直播来说开启编码容忍比如x264的tunezerolatency参数 接收端良好的错误隐藏算法是性价比最高的组合。5.3 多路冗余与主备流切换的工程实践对商业直播场景单纯靠纠错已经不够更保险的是双路并行。具体做法是推流端同时发送两路流到不同节点的接收端播放器同时接收实时校验哪一路质量更好就切哪一路。一条链路劣化时切换过程在播放器内部完成观众几乎无感。这是成本最高的方案但也是效果最好的。我在一些重要会议直播里用过这种架构当时A路的丢包率在高峰期到了5%但因为B路始终很健康观众看到的画面始终是流畅的。副路流可以降低画质、降低码率以节省带宽只需要保证不断流即可即使偶尔出现马赛克也能被主路覆盖。6. 网络侧逐层排查清单从家里的路由器到CDN节点如果推流端和接收端都优化过了丢包率还是下不来那就必须动手治理网络本身了。这一节是排障时的逐层检查清单我按实际操作的顺序排列。6.1 主播本地的网络体检项目有线连接优先于无线如果是笔记本推流坚决用网线如果是手机直播尽量靠近路由器。测上行带宽用运营商提供的测速工具或者本地能跑满上行的工具实测不要相信套餐标称值。检查路由器CPU和会话数登录路由器管理界面看CPU占用率和当前连接数。如果CPU持续超过50%就该考虑换一台转发能力更强的路由器。检查网线质量在路由器上查看WAN口的协商速率如果显示是100Mbps而不是1000Mbps说明网线或者端口有问题。关闭不必要的后台上传直播期间关掉网盘同步、视频监控上传、系统自动更新等一切占用上行的进程。6.2 路由器上有用的配置项QoS设为对上行优先很多游戏路由器的QoS是给下行加速的这种设置对直播没用。需要手动把主播设备的IP地址设置到上行优先级最高的队列。MTU值适当调低默认MTU是1500在部分PPPoe拨号线路上实际可用值是1492。如果发现大包丢包、小包不丢很可能就是MTU问题把路由器WAN口的MTU调到1492甚至1400试试。关闭IPv6或者确保IPv6路由稳定有些运营商环境的IPv6路径质量比IPv4差如果推流域名解析优先使用了IPv6地址也可能导致大包丢包。6.3 CDN和云服务节点的选型判断如果本地链路健康、推流到端侧测试服务器也没问题但观众依然反映卡顿那就要检查CDN节点这一层了。判断方法联系平台方拿到观众所在区域的拉流节点信息然后从你自己的网络去ping观众侧节点。如果响应很差说明平台调度有问题。这时候能做的就是通过平台控制台去修改调度策略或者在直播拉流URL上增加参数比如指定ge参数让特定区域的观众切到备用节点。选型方面尽量选择提供多线路冗余的CDN服务商很多知名平台在控制台能手动切换电信/联通/移动线路。每次直播前我自己都会做一次线路验证在开播前30分钟用模拟拉流测试三线电信联通移动的丢包率发现问题立刻换线路。7. 实测复盘一次典型的直播丢包排查过程聊完方法论分享一个相对完整的排查案例。某主播团队向我反馈每次直播到40分钟左右观众就开始大量投诉卡顿而主播自己看的时候一切正常重启直播后能顶一阵子但过一会又复发。我先去了他们的推流现场。第一步sin用有线连接替代原来的Wi-Fi戴了一个小时问题依旧存在。第二步做iperf3连续测试发现了一个有意思的现象刚开始跑测试时丢包率是0.02%持续跑了20分钟后丢包率缓慢爬升到了0.6%。这说明什么链路不是一开始就坏而是随着时间推移逐渐劣化的。这个特征指向某一个环节出现了累计性资源耗尽。我立刻登录路由器管理界面果然发现CPU占用率从开播时的10%爬升到了65%NAT会话数已经逼近上限。进一步观察发现这台路由器同时承载着直播推流、观众端预览、后台文件上传、以及主播手机上若干个APP的持续请求。大量短连接导致NAT会话表快速填充路由器转发性能逐级下降。处理方案如下关掉所有后台非关键上传任务释放上行带宽在路由器上把推流设备的IP设为静态地址并开启上行QoS最高优先级给路由器加了一台硬路由做拨号原路由器只做交换减轻转发压力推流协议从RTMP切换为SRT在客户端开启FEC冗余。改动上线后连续三场直播的收端丢包率稳定在0.05%以内观众反馈恢复正常。这个案例的启发是很多丢包问题的根源是一个粒度的资源瓶颈被持续消耗而不是单次大流量冲击。排查丢包时不要只盯瞬时值更要从开播后第几分钟开始变差这个时间轴上找线索。8. 最后聊聊治本的几个习惯做了大量排障之后我最大的体会是完全避免丢包是做不到的但把丢包控制在观众无感的范围内是完全可以做到的。以下这几个习惯帮我在很多项目里少踩坑每次直播前固定做一次开播体检上行带宽测试、大包ping测试、推流端日志确认没有NRP非正常丢包告警。推流码率永远留出20%以上余量。宁可画质略低不要赌带宽峰值。广播级直播音乐会、发布会这类一定要做双链路冗余只是价格问题不是技术问题。遇到棘手的丢包用时间轴排查法记录出问题的起始时间点回溯那个时间点前后网络、设备、负载的变化往往能一击命中。如果看完这篇内容还有疑问最直接的建议是先做一轮3.2节里的iperf3测试拿到你那一路的真实丢包数据再决定从哪一层着手优化。数据永远比感觉更靠谱。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →