根本原因是TCP重传与应用层超时分属不同层级,内核重传常在应用感知前完成;业务无超时仅说明系统调用最终返回,不反映中间是否经历重传或乱序。

为什么 Dup ACK 和 Retransmission 不一定触发业务超时
根本原因是 TCP 重传和应用层超时属于不同层级的机制,且重传常在应用层感知前就完成了。业务日志没报超时,不代表网络没问题;它只说明 read() 或 write() 系统调用最终返回了,哪怕中间经历了重传、乱序、延迟确认等过程。
常见误解是把「TCP 层重传」等同于「应用层请求失败」,但实际中:
- 应用层超时(如 HTTP client 的 timeout=5s)从发起请求那一刻开始计时,而 TCP 重传发生在内核协议栈,只要重传后数据最终送达,应用读写就能完成
- 内核 TCP 栈默认启用快速重传(tcp_fastretrans)、SACK、时间戳等优化,很多丢包在几十毫秒内就恢复了,远低于应用层超时阈值
- 如果服务端处理快、客户端不校验响应完整性(比如没校验 HTTP Content-Length 或分块边界),即使部分重传导致响应体错乱,也可能被静默接受
如何确认 Dup ACK / Retransmission 是真丢包还是误判
tcpdump 显示大量 Dup ACK 和 Retransmission 可能是真实丢包,也可能是抓包位置不当造成的“假象”。关键看抓包点是否在路径关键节点:
- 如果在客户端机器抓包,看到自己发的包被重传 → 很可能客户端到服务端之间有丢包(防火墙限速、网卡驱动 bug、交换机 buffer 溢出)
- 如果在服务端机器抓包,看到客户端重传 → 需结合服务端
netstat -s | grep -i "retran"确认是否收到原始包:若服务端TcpExtTCPDupAck高但TcpInSegs正常,说明 Dup ACK 是服务端发出的(即客户端丢响应),不是客户端丢请求 - 如果在中间设备(如负载均衡器)抓包,看到大量 Dup ACK 但无对应重传包 → 很可能是该设备未开启 SACK 或窗口缩放,导致接收端反复发送重复 ACK,触发发送端误重传
一个快速验证方式:
ss -i src_ip:src_port dst_ip:dst_port
查看当前连接的
cwnd、ssthresh、rtt 和 retrans 计数。如果 retrans 持续增长但 cwnd 没明显下降,大概率是瞬时拥塞而非持续丢包。
哪些场景下业务完全无感但 tcpdump 异常明显
以下情况会导致 tcpdump 抓到高频重传/Dup ACK,但业务日志干净:
- 服务端启用了
TCP_NODELAY但客户端未启用,小包频繁触发 Nagle 算法与 Delayed ACK 协同失效,造成“伪重传”(实际是 ACK 延迟引发的快速重传误触发) - 网络路径存在微突发(microburst),交换机队列瞬间打满丢包,但平均带宽正常 →
ping测不出丢包,tcpdump却能看到局部重传 - 客户端或服务端 TCP 时间戳(
tcp_timestamps)关闭,导致 RTT 估算失真,RTO 设置过小,轻微延迟就被判定为丢包并重传 - 使用 TLS 1.3 + 0-RTT,首次请求在 handshake 完成前就发出了,若 handshake 包丢失,重传的是 handshake 而非业务数据,业务层只看到连接建立稍慢
下一步排查该盯什么,而不是继续看 tcpdump
tcpdump 是现象入口,不是根因终点。当看到大量 Dup ACK/Retransmission 但业务无异常时,优先检查这些:
- 确认两端
/proc/sys/net/ipv4/tcp_reordering是否一致(默认 3)。若一端设为 1,另一端为 6,容易因乱序误判重传 - 查服务端
netstat -s中TcpExtTCPDelivered与TcpOutSegs的比值:若显著低于 1,说明大量数据被重传后才交付,虽未超时但有效吞吐已受损 - 用
ethtool -S eth0查网卡收发队列丢包(rx_missed_errors、tx_aborted_errors),比tcpdump更接近物理层真相 - 检查 BPF 过滤器或 eBPF 工具(如
bpftrace -e 'kprobe:tcp_retransmit_skb { printf("retrans %s:%d -> %s:%d\\n", args->sk->__sk_common.skc_rcv_saddr, ntohs(args->sk->__sk_common.skc_num), args->sk->__sk_common.skc_daddr, ntohs(args->sk->__sk_common.skc_dport)); }')定位具体哪个连接、哪个 socket 在反复重传
真正难定位的,往往是那些重传后立刻恢复、不触发 RTO、也不影响单次请求耗时的微抖动 —— 它们不会出现在业务日志里,却在悄悄抬高 P99 延迟、降低连接复用率。这时候,tcpdump 是起点,不是答案。










