快重传是什么
快重传是 TCP 在「等超时」之外更快发现丢包的机制。接收方收到乱序段时,会立刻重复确认它期望的那个序号;发送方连续收到 3 个重复 ACK 就判定该段丢失并马上重传,不必等 RTO 计时器走完。一个 RTO 往往几百毫秒到几秒,省下的这段时间直接体现在弱网下的响应速度上。
基本信息
| 触发条件 | 连续收到 3 个重复 ACK(RFC 5681 建议阈值) |
|---|---|
| 配套机制 | 快恢复(Fast Recovery):重传后窗口减半而非回到 1 个 MSS |
| 明显局限 | 一个窗口内丢多个段时重复 ACK 数量不足,需 SACK 配合 |
| 观测手段 | 抓包看 duplicate ack,内核计数看 FastRetrans 与 Timeouts |
| 相关开关 | net.ipv4.tcp_sack、net.ipv4.tcp_dsack 默认开启 |
典型使用场景
- 分析弱网吞吐偏低:看重传主要靠快重传触发还是靠 RTO 超时
- 区分「真丢包」与「网络乱序」造成的伪重传,避免误判链路质量
- 评估 SACK 是否生效:未开启时一个窗口内多丢包只能等超时
- 复盘某次卡顿:抓包里是否出现成串 dup ack 之后紧跟一次重传
- 对比两台机器的内核计数,定位是个别实例还是全链路问题
- 调优长肥管道(高带宽高时延)连接时,确认丢包恢复策略是否够快
最小示例
最小示例
tcpdump -nn -i eth0 'tcp port 8080 and tcp[tcpflags] & tcp-ack != 0' -c 50 # 看重复 ACK
# Wireshark 过滤器:tcp.analysis.duplicate_ack / tcp.analysis.fast_retransmission
nstat -az | grep -E 'TcpExtTCPFastRetrans|TcpExtTCPTimeouts|TcpExtTCPDSACKRecv'
sysctl net.ipv4.tcp_sack net.ipv4.tcp_dsack # 确认选择性确认与 DSACK 是否开启
ss -ti | grep -i -E 'retrans|reordering' # 单连接的重传与重排序计数相关内核计数怎么读
| 计数项 | 含义 | 判断方向 |
|---|---|---|
| TcpExtTCPFastRetrans | 由快重传触发的重传次数 | 相对超时次数越高,说明丢包发现得越及时 |
| TCPTimeouts | RTO 超时触发的重传次数 | 持续增长说明链路质量差或延迟抖动大 |
| TCPDSACKRecv | 收到重复段通知的次数 | 偏高说明存在伪重传,发送方重发了对端已收到的数据 |
| TCPOFOQueue | 乱序队列相关统计 | 偏高说明是网络乱序而非丢包 |
| TCPSackRecv | 收到的 SACK 块数量 | 为 0 且丢包频繁时要检查 SACK 是否被中间设备破坏 |
阈值 3 是经典实现。DSACK 是区分真丢包与乱序伪重传的关键手段,Linux 默认开启,与 SACK 配合使用。