这是《计算机网络 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 流量控制保护接收方,拥塞控制保护网络。TCP 拥塞控制通过拥塞窗口、慢启动、拥塞避免、快速恢复和多种算法,在丢包或时延信号中探测可用容量。理解拥塞控制,才能解释为什么跨地域长肥网络吞吐低、为什么少量丢包影响巨大、为什么 BBR 在弱网下表现不同。
10.1 拥塞窗口与接收窗口
实际发送窗口:
send window = min(cwnd, rwnd)
| 窗口 | 保护对象 |
|---|---|
| rwnd | 接收方处理和缓冲能力 |
| cwnd | 网络承载能力 |
拥塞控制演进:
| 阶段 | 算法 | 核心信号 |
|---|---|---|
| 传统 | Tahoe / Reno | 丢包 |
| 改进 | NewReno、SACK | 丢包恢复 |
| 时延 | Vegas | RTT 增长 |
| 现代内核常用 | CUBIC | 丢包,三次函数窗口增长 |
| 基于带宽时延 | BBR | 带宽与 RTT |
查看当前算法:
sysctl net.ipv4.tcp_congestion_control
查看可用算法:
sysctl net.ipv4.tcp_available_congestion_control
10.2 慢启动
初始窗口较小,每个 RTT 内近似指数增长:
RTT 1: cwnd = 10
RTT 2: cwnd = 20
RTT 3: cwnd = 40
达到慢启动阈值后进入拥塞避免:
cwnd < ssthresh:慢启动
cwnd >= ssthresh:拥塞避免
慢启动并不慢,它的起点低但增长快。短连接可能刚完成慢启动就关闭,无法充分利用带宽。
10.3 拥塞避免与丢包响应
拥塞避免阶段线性增长:
每个 RTT cwnd 增加约 1 MSS
发生超时:
ssthresh = cwnd / 2
cwnd = 初始窗口
重新慢启动
快速重传触发:
ssthresh = cwnd / 2
cwnd 降半并进入快速恢复
传统丢包算法在高 RTT、高带宽和少量随机丢包网络中吞吐受限。
10.4 CUBIC
CUBIC 使用三次函数调整窗口,相比 Reno 对高带宽长延迟网络更友好。
特点:
- 窗口增长与 RTT 关联较弱;
- 大窗口网络收敛更快;
- 仍以丢包为主要拥塞信号;
- 是许多 Linux 版本的默认算法之一;
- 深缓冲网络可能出现缓冲膨胀。
10.5 BBR
BBR 估算瓶颈带宽和最小 RTT,目标是让发送速率接近 BDP,而不是持续填满缓冲区。
核心指标:
delivery rate:交付速率
min RTT:路径最小往返时延
特点:
| 优势 | 注意 |
|---|---|
| 弱网和高丢包下吞吐更稳 | 需要内核版本支持 |
| 减少缓冲膨胀 | 与 CUBIC 竞争时公平性需评估 |
| 适合跨地域长肥网络 | 参数调优复杂 |
| 降低排队延迟 | 不能替代容量规划 |
10.6 缓冲膨胀
路径中缓冲区过大时:
cwnd 持续增长
-> 队列变长
-> RTT 上升
-> 交互延迟变大
现象:
- 吞吐不低;
- RTT 显著上升;
- 语音和游戏卡顿;
- 大文件传输影响小请求。
缓解:
- 使用 BBR 或时延敏感算法;
- 队列管理,如 FQ-CoDel;
- 限速大流量;
- 业务流量隔离;
- 升级链路或分流。
Linux 队列规则:
tc qdisc show
10.7 拥塞控制与业务吞吐
常见吞吐异常:
| 现象 | 可能原因 |
|---|---|
| 单连接吞吐低 | RTT 高、窗口小、丢包 |
| 多连接吞吐高 | 单流受拥塞控制限制 |
| 偶发长尾 | 重传、队列、路由切换 |
| 高峰下降 | 带宽拥塞 |
| 上传下载差异 | 路径不对称 |
| 新内核变化 | CC 算法或队列规则变化 |
排查:
ss -i dst 10.20.1.10
cat /proc/net/netstat
netstat -s | grep -i retrans
重点指标:
- RTT;
- retrans;
- cwnd;
- unacked;
- 丢包率;
- 实际吞吐。
10.8 多流公平性
同一瓶颈上的多条 TCP 流会竞争带宽。传统算法通过窗口减半和探测逼近公平,但不同算法、不同 RTT 和非 TCP 流竞争时结果不同。
生产建议:
- 大文件传输与在线交易流量隔离;
- 备份任务限速;
- 使用 QoS 标识关键流量;
- 避免批量任务与用户请求共享同一出口;
- 监控队列和重传;
- 跨地域传输优先就近和分片并行。
本章小结
拥塞控制通过 cwnd 探测网络容量,慢启动指数增长,拥塞避免线性增长,丢包后减半或重新慢启动。CUBIC 改善高带宽长延迟网络表现,BBR 基于带宽和 RTT 降低对丢包和缓冲的依赖。吞吐问题应同时看 RTT、丢包、窗口、队列和并发流数量。
思考题
- rwnd 和 cwnd 分别保护什么?
- 慢启动为什么是指数增长却叫慢启动?
- 超时重传和快速重传后的窗口变化有什么不同?
- 为什么 BBR 在弱网下可能优于 CUBIC?
- 写一份跨地域文件传输吞吐低的排查清单。