4. TCP 重传机制概述:超时重传 (RTO)、快速重传、选择性确认 (SACK)
TCP 协议通过确认与重传机制保证数据的可靠交付。当发送端发出的数据段在传输过程中丢失、损坏或延迟到达时,接收端无法产生对应的确认 (ACK),发送端必须通过某种手段检测到丢失并重新发送数据。本章深入剖析三种核心重传机制:超时重传 (RTO)、快速重传 与 选择性确认 (SACK),帮助运维人员理解不同场景下的重传触发逻辑与优化方向。
排查要点: 网络丢包率超过 0.1% 时,TCP 重传事件会显著增加。区分超时重传与快速重传的比例,是定位丢包原因(拥塞 vs. 随机丢包)的关键第一步。
4.1 超时重传 (Retransmission Timeout, RTO)
超时重传是最基础、最保守的重传机制。发送端为每个发送的数据段启动一个定时器,若在定时器到期前未收到该数据段的 ACK,则判定该数据段丢失,立即重传并重置定时器。
4.1.1 RTO 计算与指数退避
RTO 的值并非固定,而是基于实时测量的 往返时间 (RTT) 动态计算。标准算法如下:
- SRTT (Smoothed RTT):平滑后的 RTT,反映网络延迟趋势。
- RTTVAR (RTT Variation):RTT 的偏差,反映延迟抖动。
- RTO = SRTT + max(G, 4 × RTTVAR),其中 G 为时钟粒度。
当发生超时重传后,TCP 会执行 指数退避 (Exponential Backoff):下一次 RTO 值翻倍,直到达到上限(通常为 60 秒或 120 秒),以减轻网络拥塞。
| 重传次数 | RTO 倍数 | 典型 RTO 值 (初始 200ms) | 说明 |
|---|---|---|---|
| 1 | 1× | 200 ms | 首次超时 |
| 2 | 2× | 400 ms | 指数退避 |
| 3 | 4× | 800 ms | 继续退避 |
| 4 | 8× | 1.6 s | 持续退避 |
| 5+ | 16× … | ≥ 3.2 s | 上限 60-120s |
运维警示: 频繁的超时重传通常意味着网络存在严重拥塞或长链路故障。指数退避会导致应用层感知到明显的“卡顿”或“连接挂起”,是用户体验下降的直接原因。
4.1.2 超时重传流程 SVG
4.2 快速重传 (Fast Retransmit)
快速重传是一种比超时重传更高效的丢包检测机制。它基于接收端发送的 重复 ACK (Duplicate ACK) 来触发,无需等待 RTO 定时器到期。
4.2.1 触发条件与流程
当接收端收到乱序的数据段时,会立即发送一个 ACK,确认最后一个按序收到的字节。发送端连续收到 3 个或更多相同的重复 ACK 时,即可推断后续数据段已丢失,立即重传,无需等待超时。
- 条件: 收到 3 个重复的 ACK(即总共 4 个相同的 ACK,包含原始 ACK)。
- 优势: 重传延迟从 RTO(通常数百毫秒)降低到 1 个 RTT(通常数十毫秒)。
- 限制: 只能重传一个数据段,无法同时恢复多个丢失的数据段。
排查技巧: 在 tcpdump 或 Wireshark 中,快速重传的特征是“TCP Fast Retransmission”标记。如果快速重传占比高,说明网络存在随机丢包或缓冲区溢出,而非严重拥塞。
4.2.2 快速重传流程 SVG
4.3 选择性确认 (Selective Acknowledgment, SACK)
SACK 是 TCP 的扩展选项,允许接收端精确告知发送端哪些数据段已成功接收、哪些丢失,从而避免不必要的重传。
4.3.1 SACK 的工作原理
在传统累积确认中,接收端只能确认连续收到的最大序列号,无法告知乱序到达的数据。SACK 通过在 TCP 选项字段中携带 SACK Block,列出已收到的非连续数据块范围。
- SACK Permitted 选项: 在 TCP 三次握手时协商,双方均支持 SACK 才能启用。
- SACK Block 格式: 每个 Block 包含 Left Edge 和 Right Edge,表示一段连续已收数据。
- 最大 Block 数量: 受 TCP 选项长度限制(40 字节),通常最多 4 个 Block。
性能提升: 在丢包率较高的网络(如无线网络)中,启用 SACK 可将重传效率提升 30%-50%,显著减少不必要的重传和带宽浪费。
4.3.2 SACK 与传统 ACK 对比
| 对比维度 | 传统累积 ACK | SACK |
|---|---|---|
| 确认粒度 | 只能确认连续数据 | 可确认多个非连续数据块 |
| 重传效率 | 低,可能重传已收数据 | 高,只重传真正丢失的数据 |
| 多丢包恢复 | 需要多次 RTT | 一次 RTT 可恢复多个丢包 |
| 选项开销 | 无额外选项 | 需 2 字节 + 8 字节/Block |
| 兼容性 | 所有 TCP 实现 | 需双方协商支持 |
4.3.3 SACK 工作流程 SVG
4.4 三种重传机制对比总结
| 机制 | 触发条件 | 重传延迟 | 适用场景 | 效率 |
|---|---|---|---|---|
| 超时重传 (RTO) | RTO 定时器到期 | 高 (RTO 值) | 严重拥塞、网络中断 | 低 |
| 快速重传 | 3 个重复 ACK | 中 (1 RTT) | 随机丢包、轻度拥塞 | 中 |
| SACK | 重复 ACK + SACK Block | 低 (1 RTT) | 多丢包、高延迟网络 | 高 |
实践建议: 现代操作系统默认启用 SACK。在排查重传问题时,优先检查 SACK 是否生效(通过 tcpdump 观察 SYN 包中的 SACK Permitted 选项)。若 SACK 未启用,建议在系统层面开启:
# Linux 查看 SACK 状态
sysctl net.ipv4.tcp_sack
# 启用 SACK
sysctl -w net.ipv4.tcp_sack=1