Skip to content

模块导航: 总入口 · 总纲与方法 · 后端场景 · AI与算法工程 · 国企与金融 · 网络问答


6. TCP 拥塞控制的四个算法(热度 310 · 高频选考) ​

Q: 描述慢开始、拥塞避免、快重传、快恢复。

A:

四个算法完整展开 ​

1. 慢开始: cwnd 从约 1 MSS 起(概念题从 1 讲起;Linux 实现按 RFC 6928 从 TCP_INIT_CWND=10 起,ss -tin 可见 cwnd:10),每 ACK cwnd += 1 MSS → 一个 RTT 内大约翻倍,直到 cwnd ≥ ssthresh。动机:「慢」指起点低先探测,不是增长慢。 2. 拥塞避免: cwnd ≥ ssthresh 后,每个 RTT cwnd += 1 MSS(线性/加性增长),即 AIMD 中的 AI。 3. 快重传: 连续收到 3 个重复 ACK 立即重传丢失段,不等 RTO。为何是 3:1 个可能是乱序;3 个说明后续包已到而中间有洞。 4. 快恢复: 快重传后 ssthresh = cwnd/2,cwnd = ssthresh(或 ssthresh+3 变体),直接进入拥塞避免而不是回 1。动机:仍有后续 ACK,网络未严重瘫痪。

与超时重传的对照(高频) ​

事件ssthreshcwnd之后阶段
超时重传cwnd/21重新慢开始(认为网络严重拥塞)
快重传+快恢复cwnd/2≈ssthresh拥塞避免(网络仍有一定交付能力)

状态机示意 ​

diagram
cwnd=1 → 慢开始指数涨 → cwnd≥ssthresh → 拥塞避免线性涨
              ↑                              │
              │         超时:ssthresh=cwnd/2, cwnd=1
              │                              │
              └──────────────────────────────┘

         3重复ACK:ssthresh=cwnd/2, cwnd=ssthresh → 拥塞避免

加分点:现代算法 ​

  • CUBIC(Linux 默认): 用三次函数窗口增长替代 Reno 线性增长,高带宽时延积网络收敛更快;以「距离上次拥塞事件的时间」为函数自变量。
  • BBR(Google): 基于带宽时延积(BDP)建模,测量瓶颈带宽与 RTT,不把丢包作为唯一拥塞信号;解决缓冲膨胀(bufferbloat)。部署上以 Google 自家服务与其自建网关(YouTube、Google 骨干等)最常见;Linux 发行版默认不启用,需先加载模块再切换:modprobe tcp_bbr → sysctl -w net.ipv4.tcp_congestion_control=bbr(未加载时 tcp_available_congestion_control 里根本看不到 bbr,本机实测只有 reno cubic)。手机系统默认仍是 CUBIC;WebRTC 走的是 GCC + transport-cc(发送端自估时延梯度)而非内核 BBR,别把这两类当成 BBR 的普及证据。
  • sysctl net.ipv4.tcp_congestion_control / sysctl net.ipv4.tcp_available_congestion_control 可查看与切换。

常见追问 ​

追问 1:慢开始为什么叫「慢」?增长是不是很慢?

  • 答题要点: 名称源于「起点低、先小心试探」,不是增长慢;指数增长其实很快。对比「一开始就全速发送」,它在起点上「慢」。

追问 2:快重传和超时重传后窗口调整有何不同?为什么?

  • 答题要点: 超时 → cwnd=1 重新慢开始(长时间无确认,可能严重拥塞);3 重复 ACK → 快恢复,cwnd 降到约一半后线性增长(仍有 ACK 流,网络未完全瘫痪)。区别体现对拥塞严重程度的分级响应。

追问 3:BDP 是什么?和 TCP 窗口有什么关系?

  • 答题要点: 带宽时延积 = 带宽 × RTT,表示「管道中能容纳的最大数据量」。发送窗口(尤其 min(rwnd,cwnd))应 ≥ BDP 才能填满高带宽长延迟链路,否则链路空闲。BBR 正是围绕 BDP 建模。对应主库第 127 题。

易错点 ​

易错说法纠正
「慢开始增长慢」起点低,但是指数增长
「3 个重复 ACK 后 cwnd=1」那是超时;3 重复 ACK 走快恢复,cwnd≈cwnd/2
「拥塞避免阶段指数增长」是每 RTT +1 MSS 的线性增长
「Linux 默认 Reno」现行默认多为 CUBIC;Reno 是教材经典参照
「丢包一定表示拥塞」传统算法这么假设;无线随机丢包、BBR 则不这么等同

与选择题对照 ​

  • 主库 150: 第 68 题(3 个重复 ACK 通常快速重传)、第 69 题(超时重传后 cwnd)、第 70 题(拥塞控制错误叙述)、第 71 题(快恢复结束后进入拥塞避免)、第 127 题(BDP)。
  • 补题 16: 补-03/补-04(GBN/SR——「3 重复 ACK」思想的理论渊源,但 TCP 实现更接近 SR)。
  • 口述联动: 选择题考「超时 vs 快恢复后 cwnd 怎么变」;面试要把「为什么分级」和 CUBIC/BBR 说清。

工程 / 抓包背景 ​

  • ss -ti: 观察 cwnd、ssthresh(若内核导出)、retrans。
  • Wireshark: 看重复 ACK 数量、重传段;tcp.analysis.fast_retransmission。
  • iperf3 / netperf: 打流观察吞吐与丢包。
  • Nginx: 对上游 TCP 一般不直接调拥塞算法;系统级可 sysctl -w net.ipv4.tcp_congestion_control=bbr(需内核模块)。
  • curl: 对比不同网络环境(高 RTT)下加载时间,可感知窗口与 BDP 问题。

持续学习,持续积累。