网络基础回顾:带宽、延迟、抖动、丢包率

做流控调试,说白了就是在跟四个数字打交道:带宽、延迟、抖动、丢包率。这四个指标就像汽车的油门、刹车、路况和轮胎抓地力——任何一个出问题,车都开不稳。

我刚开始接触 WebRTC 时,总觉得流控就是调调码率上限。后来被线上问题狠狠教育了一次,才明白:不懂网络指标,流控就是瞎调。今天咱们就把这四个指标掰开揉碎,看看它们到底怎么影响流控决策。

核心观点:流控的本质,是在这四个指标构成的约束空间里,找到最优的发送策略。任何一个指标的突变,都会触发流控状态机的状态迁移。

带宽:流控的「天花板」

带宽就是单位时间内能传输的数据量。单位是 bps(bit per second)。在 WebRTC 里,我们通常关注两种带宽:

  • 可用带宽(Available Bandwidth):链路实际能承载的速率,不是运营商给你的标称值
  • 探测带宽(Probing Bandwidth):通过发送探测包测出来的瞬时容量

我个人习惯把带宽比作水管。标称带宽是水管直径,可用带宽是当前水压下的实际流量。你想想看,水管再粗,水压不够也白搭。

流控算法对带宽的响应很直接:

  • 发送码率 < 可用带宽 → 链路稳定,延迟低
  • 发送码率 > 可用带宽 → 队列堆积,延迟飙升,最终丢包

实战经验:我在项目中遇到过运营商限速的场景。标称 100Mbps 的专线,晚高峰实际可用带宽只有 8Mbps。如果流控只认标称值,视频必然卡成幻灯片。所以一定要用实时探测的可用带宽,别信静态配置。

延迟:流控的「温度计」

延迟是数据从发送端到接收端的耗时。单位是 ms。WebRTC 里最关键的延迟指标是 单向延迟(One-Way Delay, OWD)。

为什么单向延迟这么重要?因为它是拥塞的早期信号。我举个例子:

正常链路:发送 10Mbps → 延迟 20ms
轻度拥塞:发送 12Mbps → 延迟 35ms(队列开始堆积)
重度拥塞:发送 15Mbps → 延迟 120ms(队列深度爆炸)

你看,延迟的变化比丢包来得更早。这就是为什么现代流控算法(比如 GCC)优先用延迟作为拥塞信号,而不是等丢包发生再反应。

避坑指南:我曾经踩过一个坑——用 RTT(往返延迟)代替单向延迟做流控决策。RTT 包含了对端处理时间,在服务器负载高时会产生假阳性。后来我改用接收端反馈的 OWD 估算,准确率提升了一大截。

抖动:流控的「噪音」

抖动是延迟的变化量。单位也是 ms。公式很简单:

抖动 = |当前延迟 - 平均延迟|

抖动大说明网络不稳定。比如:

  • Wi-Fi 环境下,抖动通常在 10-30ms
  • 4G 移动网络,抖动可能到 50-100ms
  • 有线局域网,抖动一般 < 5ms

流控算法怎么处理抖动?嗯,这里要注意:抖动是噪声,不是信号。流控需要区分「正常的网络波动」和「真正的拥塞信号」。

我见过不少新手把抖动当成拥塞来处理,结果码率忽高忽低,视频反而更卡。正确的做法是:用平滑滤波器(比如卡尔曼滤波)把抖动滤掉,只保留趋势信号。

抖动范围 网络质量 流控策略
< 10ms 优秀 正常探测,可激进增加码率
10-30ms 良好 适度增加,增加平滑窗口
30-80ms 一般 保持码率,加大抖动缓冲区
> 80ms 差 降低码率,启用 FEC 或 NACK

丢包率:流控的「最后防线」

丢包率是丢失的数据包占总发送量的比例。单位是百分比。WebRTC 里丢包率超过 5% 就会明显影响体验,超过 20% 基本不可用。

丢包对流控的影响分两个层面:

  1. 拥塞信号:丢包意味着链路已经过载,必须降码率
  2. 有效吞吐:丢包导致重传,实际吞吐量 = 发送码率 × (1 - 丢包率)

举个例子:你发送 2Mbps,丢包率 10%,实际有效吞吐只有 1.8Mbps。如果流控不把重传开销算进去,视频质量会持续劣化。

关键认知:丢包率不是二值信号。WebRTC 的 GCC 算法把丢包率分成三个区间:

  • 0-2%:正常,不触发降速
  • 2-10%:轻度拥塞,按比例降码率
  • > 10%:严重拥塞,立即大幅降码率

四个指标的联动关系

单独看每个指标意义不大。真正有价值的是它们之间的联动模式。我画了一张图来说明:

流控四指标联动关系图 带宽 延迟 抖动 丢包率 超载 波动 溢出 流控决策引擎 综合四个指标,输出目标码率 目标码率 / 编码器配置 ⚠ 典型拥塞演进路径 带宽超载 → 延迟上升 → 抖动加剧 → 丢包发生

从这张图能看出什么?说白了,四个指标不是孤立的。它们有一条典型的恶化路径:

  1. 带宽超载:发送速率超过链路容量
  2. 延迟上升:数据在路由器队列里堆积
  3. 抖动加剧:队列长度不稳定,延迟忽高忽低
  4. 丢包发生:队列溢出,数据包被丢弃

流控算法的核心任务,就是在第 1 步或第 2 步就做出反应,避免走到第 4 步。等丢包发生了再降码率,已经晚了。

调试技巧:我调试流控问题时,习惯同时看这四个指标的时序图。如果延迟先涨、丢包后出现,说明是拥塞导致的丢包。如果丢包先出现、延迟没变化,那大概率是链路质量问题(比如无线干扰),处理方式完全不同。

实际调试中的常见误区

最后分享几个我踩过的坑:

  • 只看平均值:平均延迟 50ms 看起来正常,但峰值可能到 500ms。流控对峰值更敏感,一定要看 P95/P99 分位值
  • 忽略接收端视角:发送端看到的延迟和接收端不一样。我建议在接收端也打日志,两边对照着看
  • 把抖动当拥塞:Wi-Fi 环境下抖动 20ms 是常态,别一看到抖动就降码率。用趋势检测代替阈值判断
  • 丢包率不区分类型:FEC 修复的丢包和 NACK 重传的丢包,对流控的影响不同。要区分对待

这四个指标,是流控调试的基石。后面章节我们会深入 GCC、BBR、Pacing 等具体算法,但无论算法多复杂,最终都是在跟这四个数字打交道。把基础打牢,后面才能调得准、调得稳。