TCP 拥塞控制的核心目标是 让发送方的发送速率匹配网络的承载能力,避免因发送过多数据导致网络拥塞(丢包、延迟飙升、吞吐量下降)。
关键参数先明确:
- 拥塞窗口(cwnd):发送方根据网络状况动态调整的发送上限,单位是报文段。
- 慢启动门限(ssthresh):区分「慢启动」和「拥塞避免」的阈值,当
cwnd < ssthresh时用慢启动,cwnd > ssthresh时用拥塞避免。
4 大核心算法是慢启动、拥塞避免、快速重传、快速恢复,它们不是孤立的,而是配合工作的完整流程。
一、 慢启动(Slow Start)
1. 触发条件
- TCP 连接刚建立时;
- 网络拥塞后(超时丢包)恢复时。
2. 工作机制
- 初始状态:
cwnd = 1(只能一次发 1 个报文段),ssthresh一般设为较大值(比如 65535 字节)。 - 增长规则:每收到一个 ACK 确认,cwnd 加 1;每轮(所有发出的报文段都被确认)下来,
cwnd翻倍(指数增长)。例:cwnd=1→发 1 个→收到 ACK→cwnd=2→发 2 个→收到 ACK→cwnd=4→发 4 个…… - 切换节点:当
cwnd增长到ssthresh时,停止慢启动,转入拥塞避免阶段。
3. 核心作用
连接刚建立时,发送方对网络状况一无所知,通过指数增长快速试探网络的承载上限,但不会一直疯长 —— 到阈值就减速。
二、 拥塞避免(Congestion Avoidance)
1. 触发条件
cwnd ≥ ssthresh 时。
2. 工作机制
- 增长规则:每轮(所有报文段被确认)后,cwnd 加 1(线性增长),不再翻倍。例:cwnd=8→发 8 个→收到 ACK→cwnd=9→发 9 个→cwnd=10……
- 拥塞判断:如果出现超时丢包,说明网络拥塞了,执行 2 个操作:
ssthresh = cwnd / 2(将门限设为当前拥塞窗口的一半,下次慢启动到这个值就减速);cwnd = 1(重置拥塞窗口,重新进入慢启动)。
3. 核心作用
避免拥塞窗口指数增长导致网络过载,用线性增长慢慢试探网络的最大承载能力,平衡吞吐量和稳定性。
三、 快速重传(Fast Retransmit)
1. 触发条件
收到 3 个重复的 ACK 确认报文(不是超时丢包)。
重复 ACK 意义:接收方收到了失序的报文段,比如应该收 seq=5,结果收到 seq=6,就会重复发 ack=5,提示发送方「seq=5 丢了」。
2. 工作机制
- 不等超时计时器到期,立即重传丢失的那个报文段;
- 不把
cwnd重置为 1,而是直接进入快速恢复阶段。
3. 核心作用
相比「超时重传」,快速重传能减少丢包后的等待时间,降低吞吐量的下降幅度。
四、 快速恢复(Fast Recovery)
1. 触发条件
快速重传之后。
2. 工作机制
- 调整门限:
ssthresh = cwnd / 2(和超时丢包一样,将门限减半); - 调整拥塞窗口:
cwnd = ssthresh + 3(加 3 是因为已经收到 3 个重复 ACK,说明这 3 个报文段已经被接收方收到,网络没那么糟); - 恢复规则:每收到一个重复 ACK,
cwnd加 1;当收到新的 ACK(确认丢包的报文段已重传成功),cwnd = ssthresh,然后转入拥塞避免阶段。
3. 核心作用
丢包后不「一刀切」重置 cwnd,而是平滑恢复发送速率,大幅减少拥塞后的吞吐量波动 —— 这是现代 TCP(比如 Reno 版本)的核心优化。
五、 完整流程示例
plaintext
新建连接 → 慢启动(cwnd指数增长)→ 达到ssthresh → 拥塞避免(cwnd线性增长)
→ 收到3个重复ACK → 快速重传 → 快速恢复 → 回到拥塞避免
(或:超时丢包 → ssthresh减半,cwnd=1 → 重新慢启动)
六、 与你的建站需求关联
你搭建「思迈时光」个人网站时,CDN 加速的核心优化点之一就是 TCP 拥塞控制参数:
- CDN 节点会调大初始 cwnd(比如从 1 改成 10),让慢启动阶段更快达到稳定速率,减少网页首屏加载时间;
- 采用更先进的拥塞控制算法(比如 BBR 算法,替代传统 Reno),基于网络带宽和延迟动态调整 cwnd,进一步提升传输速度。