摘要

  • 1986 年 10 月,Lawrence Berkeley Laboratory 到 UC Berkeley 的有效吞吐量从 32 Kbps 跌到 40 bps;链路依然繁忙,却主要在搬运无效的重传副本。
  • Jacobson、Karels 及其合作者以“分组守恒”为原则改造 4BSD TCP,把 ACK 时钟、慢启动、往返时延方差、指数退避和拥塞窗口连成发送端控制回路。
  • RFC 1122 随后把慢启动与拥塞避免写成 TCP 的 MUST。分布式运行得以延续,不是因为没有规则,而是因为一条很窄的共同规则阻止激进端点把成本甩给所有人。

四百码之外,吞吐量只剩千分之一

这场故障发生在地理距离很短的两端。Van Jacobson 与 Michael J. Karels 在 1988 年论文中记录:1986 年 10 月,Lawrence Berkeley Laboratory 到加州大学伯克利分校的路径相隔约 400 码、经过两个 IMP 跳点,有效吞吐量却从每秒 32 千比特跌至每秒 40 比特。

这不是简单的“网速变慢”。线路仍然在传包,机器仍然在发送;消失的是新数据完成交付的能力。早期实现的重传计时器无法跟上重负载下往返时延及其波动,把尚在队列里的包误判为丢失。发送端随即向已经堵塞的路径再塞一份副本。副本造成更多排队与丢包,又触发下一轮重传。恢复动作变成正反馈。

John Nagle 早在 1984 年的 RFC 896 中把这种状态称为“拥塞崩溃”。那份文档解释了由不同带宽链路组成的无连接分组网络为何可能陷入一种稳定但低效的失败状态,同时明确表示意在引发讨论,而不是发布完整标准。1986 年的伯克利路径,把此前的诊断变成无法回避、可以测量的运行事实。

接收方有空间,不等于路上有空间

原有 TCP 窗口主要解决接收端缓冲区问题:目的主机还能接收多少未确认数据?它没有回答另一件事:发送方与接收方之间的网关和链路此刻能承受多少?高速局域网主机完全可能根据接收窗口一次发出一批数据,把远慢于本地以太网的长途链路入口瞬间灌满。

修复因此没有废除接收窗口,而是在发送端增加“拥塞窗口”。真正允许在途的数据量取两者较小值。发生超时、推断路径拥塞时,窗口乘法减小;新的 ACK 稳定返回时,窗口加法增加。一个端点不需要知道全网拓扑,也不拥有中间网关,却可以让自己的发送行为适应实际路径。

“分组守恒”给这组算法提供了统一原则。连接进入平衡状态后,只有一个旧包离开网络,才允许一个新包进入。ACK 是离开的证据,也是一只从瓶颈带回来的时钟:接收端不可能以高于数据穿越瓶颈的速度产生确认,因此 ACK 的间隔可以帮助发送端形成适合路径的节奏。

新连接还没有这样的时钟,慢启动负责建立它。发送端从很小的拥塞窗口开始,随着 ACK 返回迅速扩大。它的“慢”不是永久低速;窗口按往返轮次呈指数增长。关键在于每次扩大都有路径反馈,而不是一开始就把完整接收窗口倾倒进未知网络。

计时器也必须克制。只估计平均 RTT 不够,还要估计波动,避免把延迟当丢包;连续失败时,重传间隔应指数增加。论文将拥塞窗口、慢启动、计时器、ACK 策略与快速重传放在一套运行中的 4BSD TCP 改造里。它也明确提及 Phil Karn、John Nagle 与 Raj Jain 的贡献。这不是一个孤胆英雄的神话,而是若干思想通过代码、测量与协作形成的工程链。

先让代码跑起来,再写进 MUST

实验把差异量化了。在四条流共享瓶颈的测试中,没有拥塞避免时,11,000 个发送包中有 4,000 个是重传,25 KB/s 链路的一部分有效能力凭空“消失”。启用拥塞避免后,8,281 个包里只有 89 个重传,约占 1%,链路容量也能由实际流量解释。

制度顺序同样重要。算法先进入 4BSD TCP,经跟踪测量与测试者使用,再被规范吸收。1989 年 10 月发布的 RFC 1122 判断 RFC 793 的重传超时算法已经不足,并规定 TCP 必须实现慢启动与拥塞避免的组合算法;连续 RTO 的指数退避也成为强制要求。

这条 MUST 说明早期互联网并非“任何端点愿意怎样就怎样”。标准之所以可以在这里提出共同义务,是因为违规后果不会停留在违规者本地。拒绝退让的发送端占用公共队列,让遵守规则的流承担延迟与丢包,还可能在短期看起来更“快”。RFC 2914 后来警告:厂商可能竞相推出更激进的 TCP,应用可能用大量并行连接绕开节制,最终形成所有人都必须加码的军备竞赛。

共同规则保护了规则之外的多样性。操作系统、应用、路由、商业关系与具体拥塞算法仍可不同;但共享瓶颈的参与者不能要求一种“把崩溃成本外包给他人”的互操作权。这里的约束针对的是明确的共同故障机制,而不是借稳定之名接管端点的其他选择。

端点控制的边界

Jacobson 与 Karels 没有把稳定性等同于公平。端点算法可以防止总负载长期超过网络容量,却无法保证不同流如何公平分配带宽。流量汇合在网关,只有那里拥有端点看不到的整体信息。论文因此把网关侧拥塞检测称为下一项重要工作。

后来出现的主动队列管理、ECN 与众多新算法继续补充这套架构。无线误码等情况也提醒人们,丢包不总等于拥塞。1988 年的价值不在于终结研究,而在于展示一种克制的工程方法:锁定导致共同失败的反馈回路,修改最小有效控制面,用运行数据验证,再只把维持互操作稳定所必需的部分写成共同要求。

来源与证据边界

核心事实来自 Jacobson 与 Karels 的 《Congestion Avoidance and Control》及 LBNL Network Research Group 论文索引。规范链条包括 RFC 896、RFC 1072、RFC 1122、RFC 2001、RFC 2914与 RFC 5681,当时的讨论可由 LBNL 邮件索引核对。

32 Kbps 跌至 40 bps 是一条被记录路径的数据,不代表整个互联网在同一时刻全部停摆;“某一个人拯救了互联网”也会抹去共同贡献与后续演进,因此本文不作这种夸大归因。