2. 网络拥塞模型:丢包模型与延迟模型、ECN显式拥塞通知、AIMD算法分析
聊到网络拥塞,很多人的第一反应就是“丢包了”。但说实话,丢包只是拥塞的结果,不是原因。我做了这么多年网络优化,见过太多团队把精力花在“怎么减少丢包”上,结果越优化越糟糕。为什么?因为他们没搞懂拥塞模型。
这一节,我们就把拥塞模型的底裤扒干净。丢包模型、延迟模型、ECN、AIMD,一个一个来。
2.1 丢包模型:最原始,也最粗暴
丢包模型,说白了就是“只要没收到ACK,我就认为网络堵了”。TCP的早期版本(比如Tahoe、Reno)都是基于这个思路。
核心逻辑:
- 发送方每收到一个ACK,就把拥塞窗口(cwnd)加1(慢启动阶段是翻倍)。
- 一旦发生丢包(超时或收到3个重复ACK),就认为网络拥塞了,立刻把cwnd砍半(甚至降到1)。
嗯,这里要注意:丢包模型有一个致命缺陷——它只能感知到“已经发生的拥塞”。你想想看,等你发现丢包的时候,网络其实已经堵得不行了。就像开车,等你看到前车的刹车灯亮起再踩刹车,往往已经晚了。
避坑指南:我曾经在一个数据中心项目中,发现某条链路的丢包率只有0.1%,但业务延迟却高得离谱。后来排查发现,交换机缓存早就满了,只是还没开始丢包。丢包模型完全感知不到这种“即将拥塞”的状态。
2.2 延迟模型:更精细,但更复杂
既然丢包模型太迟钝,那能不能用延迟来判断拥塞?当然可以。延迟模型的核心思想是:RTT(往返时间)变长了,说明网络开始堵了。
典型的代表是TCP Vegas和BBR。它们不依赖丢包,而是通过测量RTT的变化来调整发送速率。
Vegas的算法逻辑:
期望吞吐量 = cwnd / baseRTT
实际吞吐量 = cwnd / currentRTT
diff = (期望吞吐量 - 实际吞吐量) * baseRTT
if diff < alpha:
增加cwnd
elif diff > beta:
减少cwnd
else:
保持cwnd不变
你看,这里用到了两个阈值alpha和beta。我个人习惯把alpha设小一点(比如2),这样能更早感知到拥塞。但代价是带宽利用率会下降。这是个trade-off。
延迟模型的优点:
- 能提前感知拥塞,而不是等丢包了才反应。
- 适合对延迟敏感的业务(比如视频会议、在线游戏)。
缺点也很明显:
- RTT测量本身就有噪声,容易误判。
- 在深队列(bufferbloat)场景下,延迟模型会过度保守。
我的经验:在跨洋链路上,RTT本身就很大(比如200ms),延迟模型的效果会大打折扣。这时候我建议结合ECN一起用。
2.3 ECN显式拥塞通知:让网络主动告诉你“我快撑不住了”
丢包模型和延迟模型都是“猜”拥塞。ECN(Explicit Congestion Notification)则不同——它让网络设备主动告诉发送方:“我快撑不住了,你慢点发”。
ECN的工作原理:
- 发送方在IP头中设置ECT(ECN-Capable Transport)标记,表示“我支持ECN”。
- 当路由器检测到即将拥塞(比如队列长度超过阈值),它会把IP头中的CE(Congestion Experienced)标记置1。
- 接收方收到带有CE标记的包后,在TCP的ACK中设置ECE(ECN-Echo)标记。
- 发送方收到ECE后,立即降低发送速率,并在下一个包中设置CWR(Congestion Window Reduced)标记。
说白了,ECN就是让网络设备当“哨兵”。我在项目中遇到过一种情况:某云厂商的交换机开启了ECN,但客户端没开,结果ECN标记全被忽略了。嗯,这里要注意:ECN必须端到端都支持才能生效。
警告:ECN不是万能的。如果路由器队列配置不当(比如阈值设得太高),ECN标记可能永远都不会触发。我曾经见过一个案例,队列阈值设成了100%,结果ECN形同虚设。
2.4 AIMD算法分析:加法增,乘法减
AIMD(Additive Increase Multiplicative Decrease)是TCP拥塞控制的核心算法。它的名字就说明了全部逻辑:
- 加法增(AI):每收到一个ACK,cwnd增加1个MSS(最大报文段长度)。
- 乘法减(MD):检测到拥塞后,cwnd乘以一个小于1的因子(通常是0.5)。
为什么是“加法增”而不是“乘法增”?你想想看,如果网络带宽是100Mbps,你从1Mbps开始,用加法增要很久才能达到100Mbps。但如果是乘法增(比如每RTT翻倍),几秒钟就能占满带宽。那为什么TCP不用乘法增?因为公平性。
AIMD的公平性分析:
假设有两个流共享一条链路,它们的cwnd分别是x和y。AIMD的收敛过程是这样的:
拥塞发生时:
x_new = x / 2
y_new = y / 2
拥塞恢复后(加法增):
x_new = x + 1
y_new = y + 1
你看,乘法减让两个流的cwnd比例保持不变(x/y不变),而加法增让它们的差值保持不变(x-y不变)。最终,两个流会收敛到公平共享带宽的状态。
核心结论:AIMD保证了三个特性:
- 收敛性:多个流最终会公平共享带宽。
- 稳定性:不会出现剧烈的振荡。
- 效率性:能充分利用可用带宽。
但AIMD也有问题。我记得有一次在高速网络(40Gbps)上做测试,AIMD的“加法增”太慢了,一个流从丢包恢复后,要花好几秒才能重新占满带宽。后来我们改用了CUBIC算法(它用三次函数代替线性增长),效果好了很多。
2.5 三种模型的对比
| 模型 | 拥塞信号 | 响应速度 | 适用场景 | 典型算法 |
|---|---|---|---|---|
| 丢包模型 | 丢包/超时 | 慢(事后反应) | 传统互联网 | Tahoe, Reno, NewReno |
| 延迟模型 | RTT变化 | 中(提前感知) | 低延迟场景 | Vegas, BBR |
| ECN模型 | 显式标记 | 快(实时通知) | 数据中心、云网络 | DCTCP, ECN-enabled TCP |
我个人建议:在实际部署中,不要只依赖一种模型。比如在数据中心里,我通常会用ECN + 延迟模型组合,既能快速响应,又能避免误判。
2.6 本章知识体系
下面这张图总结了本章的核心逻辑:
一句话总结:丢包模型是“事后诸葛亮”,延迟模型是“猜”,ECN是“直接告诉你”。而AIMD,是所有拥塞控制算法的基石。
好了,这一节的内容就到这里。记住,没有完美的拥塞模型,只有最适合你场景的方案。下一节我们会聊更具体的拥塞控制算法实现,到时候再细说。