导语:在上一单元中,我们学习了“流量控制 (Flow Control)”,它解决的是接收方处理不过来的问题。但在真实的互联网中,如果所有人都全速发包,中间的路由器处理不过来怎么办?这就会导致灾难性的“网络崩溃”。本单元,我们将探究 TCP 是如何凭借天才般的“拥塞控制 (Congestion Control)”机制,拯救互联网于水火之中的。

在这里插入图片描述


1. Congestion - Basic Ideas (网络拥塞的本质)

控制拥塞的核心目的,是防止整个网络因为过载而陷入崩溃。

1.1 So, what is it? (什么是拥塞?)

拥塞产生的原因非常简单:需求 > 容量
具体表现在不同的时间尺度上:

  • 微观 (Microscopic):两个数据包在路由器端口同时碰撞。
  • 中观 (Macroscopic):多条数据流 (Flows) 瞬间耗尽了某条链路的物理带宽。
  • 宏观 (Systemic):晚高峰期间,海量用户同时挤入网络(类似春运的高速公路)。

恶性正反馈:当路由器发生拥塞开始丢包时,如果不加控制,发送方会因为超时而重传更多的数据包,导致原本就拥堵的网络雪上加霜,最终吞吐量降为零,这就是“网络崩溃 (Congestion Collapse)”。

1.2 Congestion is unavoidable (拥塞是不可避免的)

  • 为什么不把路由器的 Buffer 做得无限大?
    如果 Buffer 极大,确实不会丢包了,但数据包会在里面排队等上好几秒(Bufferbloat,缓冲区膨胀),导致端到端延迟高得离谱。这对网络利用率和实时应用来说是一场灾难。
  • 丢包是好事还是坏事?
    无意义的丢包是对上游网络资源的浪费;但适度的丢包,其实是网络在向终端发出“我快撑不住了”的警告信号。

1.3 Fairness and Throughput (公平与吞吐量的博弈)

网络设计者面临一个两难境地:是追求绝对的总吞吐量最大化,还是追求每个用户的绝对公平?

  • Max-min Fairness (最大最小公平性):这是互联网普遍认可的公平原则。核心思想是“劫富济贫”——在分配资源时,优先满足需求最小(最吃亏)的流,如果还有剩余,再平均分配给需求更大的流。坚决避免少数霸道流量挤占所有资源。

2. Congestion - Basic Approaches (应对拥塞的基础策略)

如何把网络拥塞的情况告诉发送方?有两种截然不同的流派:

2.1 Network-based (基于网络核心的策略)

让网络中间的路由器主动发声。

  • 机制:当路由器快满时,主动向终端发送 Signal(信号),告知正在拥堵。
  • ECN (Explicit Congestion Notification, 显式拥塞通知):路由器会在处理数据包时,在 IP 头部打上拥塞标记。这个标记到达目标主机后,目标主机会借助返回的 ACK 报文“搭便车”,把拥塞警告带回给源主机。

2.2 End-host based (基于终端主机的策略)

路由器什么都不用管,全靠网络边缘的终端主机自己去猜!

  • TCP Congestion Control:TCP 采用的就是这种策略。它把网络当成一个黑盒。
  • 探测机制:通过维护一个名为拥塞窗口 (Congestion Window, cwnd) 的变量,结合滑动窗口策略,利用 RTT (往返时间) 和是否丢包,来动态推测网络的拥堵程度。

2.3 AIMD (加性增,乘性减)

TCP 拥塞控制的核心算法。这是一种“慢慢增加,快速减少”的试探策略。

  • Additive Increase (加性增加):如果没有发生拥塞,发送速度“一点一点”地缓慢增加。
  • Multiplicative Decrease (乘性减少):一旦检测到拥塞(丢包),发送速度“断崖式”砍半。
  • 视觉表现:这导致 TCP 的发送窗口在时间轴上呈现出经典的 “Sawtooth” (锯齿波) 形状。

3 & 4. Congestion - AIMD 动态表现

TCP 不会刻意避免丢包,相反,“丢包”正是 AIMD 用来寻找网络容量上限的探测雷达

数学逻辑 (Single & Multiple flows)

  • 收到 ACK 时 (if received)W <- W + 1/W
    (注:意味着每收到一个确认,窗口增加 1/W,当收到一整窗 W 个确认时,窗口刚好增加 1。这保证了每经过一个 RTT,窗口大小线性 +1)
  • 发生丢包时 (if dropped)W <- W / 2
    (注:立刻将窗口砍半,给网络极大的喘息空间)

吞吐量公式

在 AIMD 算法下,一条流的长期平均吞吐量近似为:Throughput ∝ W / RTT
在多条流共享链路时,AIMD 的这种锯齿状调整,最终会在数学上奇迹般地收敛到一条代表“绝对公平”的均衡线上。


5. TCP Congestion Control Ⅰ (TCP 拥塞控制演进史)

TCP 内部维护了几个关键变量来控制速度:cwnd (拥塞窗口) 和 ssthresh (慢启动阈值)。

5.1 TCP Three Questions (TCP 的哲学三问)

设计任何可靠协议都要回答:

  1. 什么时候发送新数据? (由 cwnd 和滑动窗口决定)
  2. 什么时候重传数据? (由超时或三次重复 ACK 决定)
  3. 什么时候确认数据? (累计确认机制)

5.2 状态流转 (State Transitions)

TCP 在运行中主要在以下状态中切换:

  1. Slow Start (慢启动)
    • 名字叫“慢”,其实是指数爆炸
    • 初始窗口很小(如 1 个包),但每收到一个 ACK,窗口加 1。这意味着每个 RTT 窗口翻倍 (1→2→4→81 \to 2 \to 4 \to 81248)。
    • 目的:以极快的速度探测出当前网络的可用容量,直到触碰阈值 (ssthresh)。
  2. Congestion Avoidance (拥塞避免)
    • cwnd >= ssthresh 时,进入此阶段。
    • 退化为 AIMD 的线性增长模式,每个 RTT 窗口仅仅加 1,谨慎试探拥塞点。

6. TCP Congestion Control Ⅱ (超时与时钟机制)

6.1 RTT Estimation (RTT 估计与超时陷阱)

  • 为什么难? 现实网络中 RTT 的波动极大。如果超时时间设得太长,丢包后系统迟迟不重传,浪费时间;设得太短,又会导致把正常延迟误判为丢包,引发频繁的无效重传(加剧拥堵)。
  • Self-Clocking (自时钟机制):TCP 巧妙地利用接收方返回的 ACK 作为系统运转的“心脏起搏器”。收到一个 ACK,就代表网络腾出了一个包的空间,发送方就可以安全地注入一个新包。

6.2 Pre-Tahoe 到 Tahoe 的飞跃

  • 早期 TCP (Pre-Tahoe):完全依赖定时器超时。只要超时,就把窗口重置为 1,效率极其低下。
  • TCP Tahoe 的两大创举
    1. Fast Retransmit (快速重传):如果发送方连续收到 3 个重复的 ACK,说明后续的包到了,但中间某个包丢了。此时不等超时,立刻重传丢失的包!
    2. 但是,Tahoe 依然比较原始:无论是超时还是 3 次重复 ACK,它都会把 ssthresh 设为当前窗口的一半,然后极其保守地把 cwnd 降为 1,重新开始慢启动。

7. TCP Congestion Control Ⅲ (Reno 与 NewReno)

为了解决 Tahoe 每次丢包都要从 1 重新开始的低效问题,专家们对 TCP 进行了迭代。

7.1 TCP Reno (引入快速恢复)

  • 核心改进:丢包后不再傻傻地回到 0 点!
  • Fast Recovery (快速恢复):如果是超时丢包,Reno 和 Tahoe 一样回到 1。但如果是收到 3 个重复 ACK 触发的丢包,Reno 认为“既然还能收到 ACK,说明网络还有流通能力”。
  • 此时,Reno 直接把 cwnd 减半,跳过慢启动,直接从半山腰进入拥塞避免阶段。极大提高了网络吞吐量。

7.2 TCP NewReno (终极优化)

  • Reno 的致命弱点:如果一个发送窗口内有多个包同时丢失,Reno 的快速恢复机制会彻底混乱,导致多次将窗口减半,最终饿死自己。
  • NewReno 的优化:优化了快速恢复机制的逻辑,引入了“部分确认 (Partial ACK)”的概念。它能够敏锐地识别出一个窗口内的多次丢包,并在一次恢复周期内高效处理,避免了盲目减半。

7.3 对比总结表

版本 关键改进 收到 3 个重复 ACK 的反应 效率评价
Tahoe 引入快速重传 cwnd = 1,重新慢启动 丢包后恢复极慢
Reno 引入快速恢复 cwnd = cwnd / 2,拥塞避免 恢复快,但怕单窗多丢包
NewReno 优化多重丢包 cwnd = cwnd / 2,智能恢复 更复杂,更高效

8. TCP Congestion Control Ⅳ (拥塞控制的终极目标)

回顾 AIMD,它实际上在两者之间实现了完美的平衡:

  • Service Provider (运营商/网络层):希望 Maximize link utilization (链路利用率最大化,别让线路空着)。
  • User (终端用户):希望 Fair share (公平共享,谁也别独占带宽)。
    通过分布式的 AIMD 探测,TCP 成功避免了 Congestion Collapse,支撑起了今天庞大而繁荣的互联网。

9. Reading an RFC (阅读互联网的“宪法”)

RFC (Request for Comments) 是 IETF 发布的技术规范文档。互联网上所有的规则,都在这里面。

  • History:从 1969 年开始发布,记录了互联网从无到有的史诗。
  • Necessities (为什么要读?)
    • 写底层代码(如开发服务器、抓包工具)时的最高权威参考。
    • 网络工程师排查疑难杂症的终极词典。
  • Something Common (经典 RFC 必知)
    • TCP 协议RFC 793
    • HTTP 协议RFC 7230
    • DNS 协议RFC 1035
      (注:阅读 RFC 不需要从头读到尾,学会利用目录,找到你需要的 Protocol Header 结构和状态机定义即可。)
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐