3、网络延迟与抖动:延迟与抖动的定义、对推流的影响、使用 ping 和 mtr 进行诊断

推流卡顿,十次有八次是网络问题。而网络问题里,延迟和抖动又是最核心的两个指标。很多新手一看到卡顿就去调编码参数,其实根源可能就在网络链路上。我个人习惯,排查卡顿的第一步,永远是先看延迟和抖动。

3.1 延迟与抖动的定义

先说延迟。延迟就是数据包从你的推流端,到达服务器所花的时间。单位是毫秒。你想想看,你这边推一帧画面,过了 500 毫秒服务器才收到,那观众看到的画面自然就慢了半拍。

抖动呢?它描述的是延迟的变化程度。如果延迟稳定在 50ms,那没问题。但如果延迟在 20ms 到 200ms 之间来回跳,这就是抖动。抖动对推流的杀伤力,其实比高延迟更可怕。

核心区别一句话总结:

  • 延迟 = 数据包从 A 到 B 的单程时间。
  • 抖动 = 延迟的方差,即延迟的不稳定性。

我在项目中遇到过这样的情况:某次直播,延迟只有 30ms,按理说网络很好,但观众就是频繁卡顿。查了半天,发现抖动高达 80ms。说白了,网络在「忽快忽慢」,播放器根本来不及缓冲。

3.2 对推流的具体影响

延迟和抖动对推流的影响,是分层次的。我习惯用一张表来对比,这样更直观:

指标 正常范围 轻度异常 严重异常 对推流的影响
延迟 < 50ms 50ms - 150ms > 150ms 延迟高 → 画面延迟大,互动体验差;超过 300ms 时,连麦基本不可用。
抖动 < 10ms 10ms - 30ms > 30ms 抖动大 → 播放器频繁缓冲,画面一卡一卡;严重时直接断流。

这里有个容易忽略的点:抖动会导致码率波动。为什么?因为推流端通常有拥塞控制算法,一旦检测到网络抖动,算法会误判为「网络变差了」,于是主动降低码率。等网络恢复,码率再升回来。这一降一升,观众看到的就是画质忽好忽坏。

避坑指南:

我曾经调试一个推流 SDK,发现码率总是在 2Mbps 和 500Kbps 之间来回跳。一开始以为是编码器参数没调好,折腾了两天。最后用 mtr 一测,发现抖动高达 50ms。根源是推流服务器部署在了跨地域的机房,中间经过了好几层 NAT。后来换了就近的节点,抖动降到 5ms,码率瞬间就稳了。

所以,遇到码率波动,先别急着调编码参数,先查抖动。

3.3 使用 ping 进行诊断

ping 是最基础的工具,但很多人只会用它测延迟,忽略了其他信息。我一般这样用:

# 持续 ping 推流服务器,观察延迟和丢包
ping -c 100 -i 0.1 push.example.com

参数说明:

  • -c 100:发送 100 个包,样本量足够大。
  • -i 0.1:每 0.1 秒发一个包,模拟推流的实时性。

看输出时,我重点关注三个值:

  1. min/avg/max:平均延迟和最大延迟的差值,就是抖动的粗略估计。比如 avg=30ms, max=200ms,那抖动肯定不小。
  2. 丢包率:如果超过 1%,推流大概率会卡顿。超过 5%,基本没法看。
  3. 延迟的分布:如果延迟忽高忽低,说明网络链路不稳定。

我的小技巧:

ping 的时候,我会同时开三个终端,分别 ping 推流服务器、CDN 边缘节点、以及一个公共 DNS(比如 114.114.114.114)。对比这三个结果,能快速判断问题出在哪个环节。如果只有推流服务器延迟高,那可能是服务器端的问题;如果三个都高,那就是本地网络或运营商的问题。

3.4 使用 mtr 进行诊断

ping 只能看到端到端的结果,但中间经过哪些路由器?哪一跳出了问题?这就得靠 mtr 了。mtr 结合了 ping 和 traceroute,能显示每一跳的延迟和丢包。

# 安装 mtr(macOS 用 brew install mtr,Linux 用 apt/yum)
mtr -r -c 50 push.example.com

输出解读:

  • Host:每一跳的路由器 IP 或域名。
  • Loss%:该跳的丢包率。
  • Snt:发送的包数。
  • Last/Avg/Best/Wrst/StDev:延迟和抖动(StDev 是标准差,直接反映抖动)。

我一般这样分析 mtr 结果:

  1. 看最后一跳的丢包:如果最后一跳丢包高,但前面几跳都正常,那问题大概率在服务器端。
  2. 看中间跳的延迟突变:如果某一跳的延迟突然从 10ms 跳到 100ms,那这一跳就是瓶颈。
  3. 看 StDev 值:如果某跳的 StDev 超过 20ms,说明这一跳的抖动很大,需要重点关注。

实战案例:

有一次我排查一个推流卡顿问题,mtr 结果显示:

  • 第 1-5 跳:延迟 5ms,丢包 0%
  • 第 6 跳:延迟 120ms,丢包 15%
  • 第 7-10 跳:延迟 130ms,丢包 0%

很明显,第 6 跳是罪魁祸首。联系运营商后发现,那个节点正在做维护,路由绕路了。后来他们调整了路由,延迟降到 20ms,卡顿消失。

3.5 知识体系:延迟与抖动诊断流程

下面这张图,是我自己总结的诊断流程。每次遇到推流卡顿,我就按这个顺序来,基本不会漏掉关键点。

延迟与抖动诊断流程 延迟与抖动诊断流程 推流卡顿 第一步:ping 测端到端延迟与丢包 延迟 > 50ms 或丢包 > 1%? 是 否 检查本地网络/编码 第二步:mtr 逐跳排查 分析每一跳的 Loss 和 StDev 定位瓶颈跳(延迟突变/丢包高) 联系运营商 / 更换节点 / 优化路由 提示:mtr 的 StDev 列直接反映抖动,重点关注 > 20ms 的跳

嗯,这个流程我用了好几年,基本没失手过。你想想看,如果 ping 都正常,那问题大概率不在网络,而是编码器或播放器的问题。如果 ping 异常,mtr 能帮你精确到是哪一跳出了问题。

3.6 总结与建议

最后,我给出几个实操建议:

  • 日常监控:在推流端部署一个定时 ping 脚本,每 5 秒记录一次延迟和抖动。一旦抖动超过 30ms,自动告警。
  • 选服务器节点:用 mtr 对比多个节点的延迟和抖动,选 StDev 最小的那个。别只看平均延迟。
  • 避坑:不要只看最后一跳的丢包。有时候中间跳丢包,但最后一跳因为重传机制显示正常,实际上延迟已经上去了。

我的习惯:

每次上线新推流节点,我都会先跑一遍 mtr,把每一跳的 IP 和延迟记录下来。这样以后出问题,对比一下就知道是路由变了,还是节点本身出了问题。说白了,就是给网络链路建个「健康档案」。