3. 网络延迟与抖动:延迟和抖动的区别、如何测量网络延迟、抖动对推流的影响

说到推流卡顿,很多人第一反应就是「网速不够」。但我在实际排查中遇到过太多案例——带宽明明跑满了,画面却还是卡成幻灯片。问题出在哪?往往就出在延迟和抖动这两个容易被混淆的概念上。

说白了,带宽决定你能不能推,延迟和抖动决定你推得顺不顺。今天我们就来把这俩兄弟彻底掰扯清楚。

3.1 延迟 vs 抖动:一对孪生兄弟

先给个最直白的定义:

  • 延迟(Latency):数据包从A点到B点花的时间。单位是毫秒(ms)。
  • 抖动(Jitter):延迟的变化量。说白了就是延迟忽高忽低的程度。

举个例子你就明白了。你开车从家到公司,每天都是30分钟——这是延迟稳定。如果今天30分钟,明天50分钟,后天20分钟——这就是抖动大。你想想看,哪种情况更让人抓狂?

核心区别一句话:延迟是绝对值,抖动是变化量。延迟高不一定卡,抖动大一定卡。

我在做直播SDK优化时遇到过一件事:有个客户说他们的推流总是每隔几秒卡一下,但测出来延迟只有80ms。我一看抖动数据——峰值到了200ms。嗯,问题就出在这里。延迟80ms其实很优秀,但抖动200ms意味着网络在频繁地「急刹车」和「猛加速」,编码器根本来不及适应。

3.2 如何测量网络延迟

测量延迟的方法很多,我挑几个最实用的讲。

3.2.1 传统三板斧:ping / traceroute / mtr

ping 是最基础的。它发一个ICMP包,等对方回一个,算来回时间。但注意——ping测的是ICMP延迟,不是UDP推流延迟。有些运营商会优先丢弃ICMP包,所以ping值好看不代表推流就顺。

# 测一下到推流服务器的延迟
ping -c 10 live-push.example.com

# 输出示例
rtt min/avg/max/mdev = 12.345/15.678/28.901/3.456 ms

这里 mdev 就是抖动(标准偏差)。3.456ms的抖动,对于推流来说已经算不错了。

traceroute 能告诉你数据包走了哪些路由节点。我曾经用它发现一个诡异问题:推流到某地延迟突然从20ms飙到200ms,traceroute一看,中间多跳了一个跨洋节点——原来是路由被BGP劫持了。

traceroute -n live-push.example.com

mtr 是 ping + traceroute 的结合体。它会持续探测每一跳的丢包率和延迟变化。我个人习惯用这个做第一轮排查。

mtr -r -c 100 live-push.example.com

3.2.2 推流场景专用测量法

上面那些工具测的是网络层延迟。但推流用的是UDP,而且有FEC(前向纠错)和重传机制。所以更准确的做法是——直接在推流协议层面测。

以RTMP为例,我会在客户端和服务端同时打日志,记录每个数据包的发送时间和接收时间:

// 伪代码示例
// 发送端
uint64_t send_ts = get_current_ms();
packet.header.timestamp = send_ts;
send(packet);

// 接收端
uint64_t recv_ts = get_current_ms();
uint64_t one_way_delay = recv_ts - packet.header.timestamp;

这样测出来的延迟,才是真正的「推流延迟」。我在优化某直播平台时,就是用这个方法发现——他们的CDN节点内部转发延迟高达150ms,比公网传输还慢。

我的建议:不要只看ping值。在推流客户端和服务端同时埋点,记录RTP/RTMP包的收发时间戳,这才是金标准。

3.3 抖动对推流的影响

抖动为什么比延迟更致命?我来给你拆解一下。

3.3.1 抖动的直接后果:缓冲区震荡

推流端通常有一个发送缓冲区。编码器产出的数据是均匀的(比如每秒30帧),但网络抖动会让数据包发送不均匀——有时候一口气发出去一堆,有时候卡住发不出去。

缓冲区就会像过山车一样:

  • 抖动小的时候:缓冲区水位稳定,发送平滑
  • 抖动大的时候:缓冲区要么溢出(丢帧),要么干涸(空等)

我曾经排查过一个案例:某主播的网络延迟只有40ms,但抖动高达80ms。结果就是每3-5秒卡一次,观众体验极差。后来发现是他家宽带的光猫有问题,光功率不稳定导致间歇性丢包。

3.3.2 抖动引发的连锁反应

抖动不只是让数据发送不均匀,它还会触发一系列「并发症」:

抖动表现 对推流的影响 最终效果
瞬时延迟飙升 发送缓冲区堆积 画面延迟增大,甚至跳帧
瞬时延迟骤降 发送缓冲区干涸 编码器空转,画面卡顿
频繁波动 码率自适应算法频繁调整 画质忽高忽低,观感极差
伴随丢包 触发FEC或重传 额外带宽消耗,延迟进一步恶化

避坑指南:我曾经见过有人为了降低延迟,把发送缓冲区设成0。结果抖动一来,直接丢包率飙升到30%。记住——缓冲区不是越小越好,要根据抖动来动态调整。

3.4 延迟与抖动的测量标准

说了这么多,到底多少算好,多少算差?我整理了一个参考标准:

指标 优秀 良好 一般 差
延迟(RTT) < 30ms 30-80ms 80-150ms > 150ms
抖动(mdev) < 5ms 5-15ms 15-30ms > 30ms
丢包率 0% < 0.5% 0.5%-2% > 2%

注意,这个标准是针对「推流端到CDN边缘节点」的。如果是跨国推流,延迟200ms以内都算正常,但抖动必须控制在20ms以下。

3.5 本章核心知识图

下面这张图把延迟、抖动以及它们对推流的影响串起来了:

网络延迟与抖动对推流的影响 延迟(Latency) 抖动(Jitter) 丢包(Packet Loss) 端到端延迟增大 缓冲区水位震荡 数据重传/丢帧 推流质量劣化 画面卡顿 / 跳帧 延迟持续增大 码率自适应频繁切换 排查优先级 抖动 > 丢包 > 延迟 → 先解决抖动问题,再处理延迟

3.6 实战排查思路

最后,我分享一下自己的排查顺序。遇到推流卡顿,别急着调码率:

  1. 先看抖动:用mtr或推流日志看mdev。如果抖动超过20ms,优先解决网络稳定性问题。
  2. 再看丢包:如果丢包率超过1%,检查Wi-Fi信号、网线、光猫。
  3. 最后看延迟:延迟高但抖动小,可以通过调整缓冲区来缓解。

一个小技巧:我习惯在推流客户端画一个实时曲线图——横轴是时间,纵轴是延迟和抖动。一眼就能看出网络是「平稳的慢」还是「抽风式的卡」。前者调参数,后者换网络。

嗯,延迟和抖动这部分就讲到这里。记住一句话:抖动是推流的第一杀手,比延迟更值得你花时间去排查。