首页 › programming › 它不测带宽:撞墙退半再往上爬

它不测带宽:撞墙退半再往上爬

你每天发起的每一个请求,都跑着一道「蒙眼开车」的算法

你点开一个网页、刷一条短视频、发一条消息——这些动作背后,都有一套你看不见的算法在拼命猜测一件事:这条网络链路,现在到底能塞多少数据进去?

最反常识的地方在于:TCP 从头到尾都不知道答案。 路由器不会告诉发送方"这条线 100Mbps,分你 20Mbps";中间链路也不会发任何信号。电话网靠"提前预约一条独占线路"来解决这个问题(电路交换),而互联网走的是分组交换——所有数据像快递一样丢进同一个管道,谁也不给谁留座位。

那 TCP 怎么避免把管道挤爆?Computerphile 这期《TCP b: Additive Increase Multiplicative Decrease & 'Slow Start'》给出的答案,是一段优雅到近乎哲学的算法:它不测量带宽,它靠「撞墙」来判断速度。 不断加速,直到开始丢包——然后把那一瞬间的丢包,当作"我已经顶到天花板了"的唯一信号,立刻把速度砍掉一半,再重新慢慢往上爬。

这套算法叫 AIMD(加性增、乘性减),1988 年由 Van Jacobson 提出。它拯救了差点死掉的早期互联网,直到今天仍然是你每一比特数据的底层节拍器。Computerphile 这期把它讲得极清楚,我把它拆给你看。

视频背景卡片

项目 内容
视频标题 TCP b: Additive Increase Multiplicative Decrease & 'Slow Start'
频道 Computerphile(诺丁汉大学计算机学院出品)
发布日期 2026-06-15
配套视频 TCP a: Ensuring Your Data Gets There & in the Right Order!(讲可靠性/序号,姊妹篇)
时长 约 11 分钟(典型 Computerphile 短讲)
频道订阅 约 270 万
核心主题 TCP 拥塞控制——一台「不知道带宽」的发送机如何靠丢包自学

核心内容拆解

要点 1:TCP 的工作环境,是一片「彻底的黑暗」

视频反复强调一个前提:发送方对网络一无所知。 它不知道中间经过几个路由器,不知道每跳的带宽,不知道有多少别的流量在抢同一条管道,更不知道哪一段会先堵。

这一点是理解后面一切的钥匙。很多人默认"网络应该有某种调度,会告诉我能跑多快"——没有。互联网的设计哲学恰恰是去中心化、端到端:聪明的逻辑全部塞在通信两端的发送方/接收方里(所谓的"智能在边缘"),中间的路由器尽量傻,只管尽力转发(best-effort),甚至允许把你的包直接扔掉。

所以"该发多快"这个决策,被硬塞给了发送方自己。而发送方手里唯一能感知世界的传感器,只有两样东西:包有没有按时到达,以及往返时延 RTT 有多长。AIMD 选了前者——把丢包当眼睛。

视频原话倾向:丢包(packet loss)是拥塞的信号;本解读延伸指出,这是 Van Jacobson 把"网络不告诉你"这个缺陷,翻转成了"丢包替你说话"的机制。

要点 2:1986 年,互联网差点把自己撑死

要看懂 AIMD 有多重要,得先看它救的是什么。1986 年 10 月,ARPANET(互联网前身)发生了一场著名的拥塞崩溃(congestion collapse):某两台主机之间的有效吞吐量,从 32 kbit/s 暴跌到 40 bit/s——掉了一千倍。

注意,链路没有坏,路由器没有断电。死因是正反馈死亡螺旋:

这是典型的"悲剧循环":每个发送方都在为已死的连接抢救,整个网络被重传垃圾淹没。Van Jacobson 后来在论文里描述这种状态为"拥塞崩溃"。没有任何一台机器出故障,系统却接近停摆——这是分布式系统里最可怕的一种失败模式,也叫公地悲剧。

AIMD 就是为打破这个螺旋而生的。

要点 3:Van Jacobson 的天才反转——丢包不是故障,丢包是仪表盘

视频最精彩的洞察,我认为是这一句的潜台词:绝大多数人把"丢包"当成要消灭的 bug,Van Jacobson 把它当成了唯一的信号源。

在 AIMD 设计里,一个包被丢弃,发送方不会愤怒地重发更多,而是读懂成一句暗语:"你发太快了,管道满了。" 于是它主动减速。这个翻转是整个互联网能扩展到今天规模的关键——它把"不可靠、会丢包"这件看起来是缺陷的事,变成了一个几乎免费的、天然的拥塞反馈通道。不需要路由器额外发任何控制报文,不需要任何集中调度,丢包本身就携带了信息。

本解读延伸:这正是"端到端原则"(end-to-end principle)的胜利——把复杂判断放到边缘,让核心网络保持极简。

要点 4:AIMD——加 1 要等一整圈,砍半只要一瞬间

AIMD 是两个动作的缩写,视频分别拆开讲:

这里的非对称是刻意设计的,也最有味道:往上试探要温柔(加 1),往下认错要果断(砍半)。 为什么?因为"超过了"是确定的事实(你已经撞墙了),必须马上退够;而"还能不能再快一点"是不确定的,只能小心翼翼地一步步试。

这里需要澄清一个常见误解——AIMD 操作的不是"发送速率",而是"拥塞窗口 cwnd":发送方同时在途、未被确认的包的数量上限。cwnd 越大,允许塞进管道的"飞行中的包"越多,等效于发得越快。视频用窗口来讲解,比直接讲"速率"更准确。

要点 5:那道著名的锯齿

把 cwnd 随时间画出来,你会看到一条锯齿(sawtooth):缓慢地线性爬升,爬到某个高度突然被砍一半,然后再缓慢爬升……周而复始。

cwnd
 ↑
 │      /\      /\      /\
 │     /  \    /  \    /  \
 │    /    \  /    \  /    \
 │   /      \/      \/      \
 └──────────────────────────────→ 时间
   线性爬升  丢包→砍半  线性爬升

这条锯齿告诉你的事比想象的多:

要点 6:「慢启动」其实快得吓人

视频标题里的第三个词 Slow Start,是最容易被名字骗到的一个概念。慢启动一点都不慢,它是指数增长。

机制是:连接刚建立时,cwnd 从 1 开始;每收到一个 ACK,cwnd 加 1。但因为窗口翻倍意味着这一轮能发出两倍的包,所以每个 RTT 内 cwnd 翻一倍:1 → 2 → 4 → 8 → 16 → 32……

那为什么叫"慢"?它是相对的慢——相对于早期 TCP"连接一上来就把整个接收窗口全砸出去"的野蛮行为,从 1 起步一点点长,就算"慢"了。所以记住这句口诀:

慢启动 = 指数起飞;拥塞避免(AIMD)= 线性巡航。

什么时候从"指数起飞"切换到"线性巡航"?当 cwnd 触碰到一个阈值 ssthresh(slow start threshold) 时,就退出慢启动,进入线性爬升的 AIMD 阶段。而每次发生丢包,ssthresh 会被设为当前 cwnd 的一半——这意味着系统会"记住"上次撞墙的高度,下次别一头撞上去。

要点 7:公平性是个涌现的奇迹

AIMD 最厉害的地方,是它让互不通信的多个连接,自动收敛到公平共享。这是 Chiu 和 Jain 在 1989 年证明的性质(Chiu-Jain fairness)。

直觉是这样:假设一条瓶颈链路上有两个流 A 和 B,A 发得快、B 发得慢。路由器丢包时,谁发得多谁挨的丢包也多(丢包概率大致和发送速率成正比)。于是 A 更容易被砍——它本来就大,砍半掉得更多;B 本来就小,砍半掉得少。几轮下来,两人就拉平到差不多的大小。

没有任何中央仲裁,公平是自己冒出来的(emergent)。 这也是为什么你能一边下载一边流畅视频通话——每个连接都在自私地探测,合在一起却奇异地自组织成了一种秩序。这是分布式系统设计里"用简单局部规则产生全局秩序"的教科书案例。

要点 8:从「撞墙」到「看路」——现代 TCP 的叛逃

视频聚焦经典 AIMD(对应 TCP Reno/Tahoe 时代),但作为延伸,我必须告诉你:纯粹靠"丢包当信号"这套,今天已经被部分抛弃了。 原因有两个:

  1. 高带宽下的探测困境:在 10Gbps 链路上,要让窗口大到足以"撞墙",需要极低的丢包率(比如 10⁻⁹ 量级),现实中根本等不到自然丢包,TCP 会一直爬不上去。
  2. Bufferbloat(缓冲区膨胀):现代路由器缓冲区做得太大,包不会丢,只会排队。结果是延迟飙升(游戏 ping 爆表、视频卡顿),而丢包信号迟迟不来——AIMD 被大缓冲区骗了。

于是两条路线兴起:

本解读延伸:从 AIMD 到 BBR,是从"靠撞墙感知世界"进化到"主动测量世界"。这个转向本身就是一次认知升级。

知识结构图:TCP 拥塞控制状态机

flowchart TD
    START["新连接<br/>cwnd = 1, ssthresh = 初始值"] --> SS["慢启动 Slow Start<br/>每 RTT cwnd 翻倍(指数增长)<br/>1→2→4→8→16…"]
    SS -->|"cwnd ≥ ssthresh"| CA["拥塞避免 Congestion Avoidance<br/>AIMD:每 RTT cwnd + 1(线性爬升)"]
    CA -->|"收到 3 个重复 ACK<br/>= 轻度丢包(快重传)"| FR["快恢复 Fast Recovery<br/>ssthresh = cwnd/2<br/>cwnd = ssthresh + 3"]
    CA -->|"超时 RTO<br/>= 严重丢包"| TO["ssthresh = cwnd/2<br/>cwnd = 1(彻底重来)"]
    FR --> CA
    TO --> SS

    classDef slow fill:#fde68a,stroke:#b45309,color:#000;
    classDef avoid fill:#bbf7d0,stroke:#15803d,color:#000;
    classDef recover fill:#bfdbfe,stroke:#1d4ed8,color:#000;
    classDef timeout fill:#fecaca,stroke:#b91c1c,color:#000;
    class SS slow;
    class CA avoid;
    class FR recover;
    class TO timeout;

这张图把视频里的四个状态——慢启动、拥塞避免、快恢复、超时重传——串成了一条完整逻辑:丢包的"严重程度"决定了你退到哪一步。三次重复 ACK 是"轻撞"(减半但不停),超时是"重撞"(清零重来)。

实战启示:这套算法对今天的你意味着什么

如果你是后端 / 网络工程师,理解 AIMD 直接关系到三件实事:

第一,开启 BBR 能显著改善长肥管道(高带宽×高延迟)的吞吐和延迟。Linux 上一行就能切:sysctl net.ipv4.tcp_congestion_control=bbr(需内核 ≥ 4.9)。BBR 不再傻等丢包,对跨地域、跨洲的 API 调用尤其有效。

第二,延迟突然飙升,往往不是"网慢",而是 bufferbloat。当你的服务卡顿却查不出丢包,先怀疑中间链路的缓冲队列。解决思路是减小队列深度(CoDel / FQ-CoDel 算法),让丢包信号早点出现,而不是让包在缓冲区里苦等。

第三,AIMD 是一套可以迁移到别处的工程哲学:试探要轻、认错要狠。负载均衡里限流器遇错就快速降权、爬虫的指数退避(exponential backoff,本质就是"乘性减")、微服务的断路器(circuit breaker)——全是同一个思想家族。学会它,你就掌握了一类"自适应控制"的模板。

如果你只是个普通用户,记住一条认知升级:互联网从来不是"想发多少发多少",而是"发到刚好撞墙再退半"。 你看到的流畅,是无数连接在各自锯齿式试探后,集体达成的一种脆弱而精妙的平衡。下次视频卡一下,那大概率不是服务器挂了,而是某个 TCP 连接刚刚"撞了一次墙",正在砍半后重新往上爬——给它一两秒。

延伸学习路径

  1. Van Jacobson, "Congestion Avoidance and Control", SIGCOMM 1988 —— 拯救互联网的那篇原始论文,AIMD 与慢启动的出生证。强烈建议读 Section 1 的动机部分。
  2. Computerphile 配套姊妹篇《TCP a》(https://www.youtube.com/watch?v=IADOV8UZO34)—— 讲序号、重传、如何保证数据"按顺序、不丢"地到达,和本文这一期正好拼成完整的 TCP 两面:可靠性 + 不堵死。
  3. W. Richard Stevens,《TCP/IP Illustrated, Volume 1》 —— 把窗口、RTT、重传定时器讲到骨子里的经典,AIMD 的工程细节都在这里。
  4. Cardwell et al., "BBR: Congestion-Based Congestion Control", ACM QUEUE 2016 —— Google 团队讲述为什么抛弃"丢包当信号"、改用带宽×延迟模型,是理解现代 TCP 的必读。
  5. gettys/bufferbloat.net 关于 Bufferbloat 的系列文章 —— 看懂"为什么你的网络又慢又卡",以及 CoDel/FQ-CoDel 如何收拾大缓冲区惹的祸。

参考来源

  1. TCP b: Additive Increase Multiplicative Decrease & 'Slow Start' — Computerphile — 本文深度解读的核心视频
  2. TCP a: Ensuring Your Data Gets There & in the Right Order! — Computerphile — 可靠性与顺序,姊妹篇
  3. Van Jacobson, Congestion Avoidance and Control, SIGCOMM 1988 — AIMD 与慢启动的原始论文
  4. Chiu & Jain, Analysis of the Increase/Decrease Algorithms for Congestion Avoidance, 1989 — AIMD 收敛到公平性的数学证明
  5. BBR: Congestion-Based Congestion Control — Google / ACM QUEUE — 现代背离"丢包信号"路线的代表作

一句话总结

TCP 不知道自己能跑多快,于是它蒙着眼一路加速,把撞墙(丢包)当速度计——撞一次砍半,再慢慢爬回去,靠这种笨拙的锯齿,养活了整个互联网。

本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护,聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。

完成摘要

下一步计划

注意事项

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入