超时重传与 RTO 计算
为什么需要超时重传
TCP 承诺可靠传输,但 IP 网络可能丢包。发送方发出数据后,如果在合理时间内未收到 ACK,必须重传——这就是**超时重传(Retransmission Timeout, RTO)**机制。
RTO 的核心挑战:设太短,网络轻微延迟就触发不必要的重传(加剧拥塞);设太长,丢包后迟迟不恢复(降低吞吐)。RTO 必须动态自适应网络状况。
RTT 测量
RTT(Round-Trip Time,往返时间)= 报文发送时刻 → 收到对应 ACK 时刻的差值。
关键问题:如何确定 ACK 对应哪个报文?
Karn 算法:解决重传歧义
当定时器超时触发重传后,发送方无法区分收到的 ACK 是对原始报文还是重传报文的确认。Karn 算法规定:
重传后的 ACK 不用于更新 RTT 估计
指数退避(Exponential Backoff):每次重传后,RTO 加倍,直到上限(通常 64 秒)。
第 1 次重传:RTO = 2 × 当前 RTO
第 2 次重传:RTO = 4 × 原始 RTO
第 3 次重传:RTO = 8 × 原始 RTO
...
上限:RTO ≤ 64 秒
RTO 标准算法(RFC 6298)
RFC 6298(替代 RFC 793 的原始算法)定义了现代 TCP 的 RTO 计算:
初始化
SRTT = 首次测量的 RTT
RTTVAR = 首次测量的 RTT / 2
RTO = SRTT + 4 × RTTVAR
后续更新(收到新 RTT 样本时)
RTTVAR = (1 - β) × RTTVAR + β × |SRTT - RTT_sample|
SRTT = (1 - α) × SRTT + α × RTT_sample
RTO = SRTT + 4 × RTTVAR
传统取值:α = 1/8,β = 1/4
边界约束
- RTO ≥ 1 秒(防止过短)
- RTO ≤ 上限(通常 64 秒)
- 重传后 RTO 加倍(指数退避)
计算示例
假设 α=1/8, β=1/4
第 1 次:RTT=100ms
SRTT = 100ms
RTTVAR = 50ms
RTO = 100 + 4×50 = 300ms
第 2 次:RTT=120ms
RTTVAR = 3/4×50 + 1/4×|100-120| = 37.5 + 5 = 42.5ms
SRTT = 7/8×100 + 1/8×120 = 87.5 + 15 = 102.5ms
RTO = 102.5 + 4×42.5 = 272.5ms
第 3 次:RTT=90ms
RTTVAR = 3/4×42.5 + 1/4×|102.5-90| = 31.875 + 3.125 = 35ms
SRTT = 7/8×102.5 + 1/8×90 = 89.6875 + 11.25 = 100.9375ms
RTO = 100.9375 + 4×35 = 240.9375ms
观察:RTT 波动大时,RTTVAR 增大,RTO 保守;RTT 稳定时,RTTVAR 减小,RTO 激进。
时间戳选项与更精确的 RTT 测量
RFC 7323 引入时间戳选项后,RTT 测量更精确:
发送方在报文中放入 TSval(发送时刻)
接收方在 ACK 中回显 TSecr = 收到的 TSval
发送方收到 ACK 后:RTT = 当前时刻 - TSecr
优势:
- 每个报文都有独立的时间戳,ACK 对应关系明确
- 窗口大、ACK 稀少时仍能频繁采样 RTT
- 支持 PAWS(防序列号回绕)
本篇小结
- RTO 是 TCP 可靠性的最后防线,必须动态自适应
- RTT 测量存在重传歧义:无法区分 ACK 对应原始报文还是重传报文
- Karn 算法:重传后的 ACK 不用于更新 RTT,RTO 指数退避
- RFC 6298 标准算法:SRTT + 4×RTTVAR,α=1/8, β=1/4
- 边界:RTO ≥ 1 秒,重传后加倍,上限 64 秒
- 时间戳选项:更精确的 RTT 测量 + PAWS
动手实践
查看 Linux RTO 相关参数:
sysctl net.ipv4.tcp_rto_min sysctl net.ipv4.tcp_retries2Wireshark 抓包观察重传:
- 过滤
tcp.analysis.retransmission - 观察原始报文与重传报文的时间差(即 RTO)
- 过滤
用
tc模拟延迟,观察 RTO 自适应:sudo tc qdisc add dev eth0 root netem delay 100ms # 测试后删除 sudo tc qdisc del dev eth0 root手工计算:假设 SRTT=200ms, RTTVAR=50ms,新测得 RTT=300ms,更新后的 RTO 是多少?