抓包看到大量 TCP Retransmission,先别急着扩容:一套可直接复用的网络抖动排查清单
凌晨 2 点,某业务 API 的 P95 延迟突然从 180ms 拉到 1.8s。应用日志没有报错,数据库连接池也没打满,CPU 和内存看起来都还正常。值班同学第一反应是“流量涨了,先扩机器”。但真正把一段 5 分钟的流量抓下来后,问题并不在应用层,而是在链路上出现了持续性的 TCP Retransmission(重传) 和少量 Out-of-Order。继续沿着网卡、交换路径和连接状态排查,最后发现是某台新接入节点启用了不合适的网卡 offload 与队列配置,叠加高峰时段的突发流量,导致丢包与抖动被放大。
这类问题在运维现场非常常见:监控先报警的是“接口慢了”,但真正的根因常常躲在链路抖动、队列拥塞、丢包、重传和连接复用策略里。本文不讲空泛趋势,只回答一线工程师真正会问的问题:TCP 重传到底是什么、什么时候该抓包、怎么判断是应用慢还是网络抖、与传统“看 CPU/内存/带宽”方案有什么边界差异,以及一套能落地的排查清单。
一句话定义:当发送方在预期时间内没有收到对端确认(ACK)时,会重新发送 TCP 报文,这就是 TCP Retransmission。它本身不是故障名,而是链路质量、拥塞状态或主机栈行为异常的结果信号。
什么是 TCP Retransmission
很多团队把“看到重传”直接等同于“网络有问题”,这不够准确。重传更像一个结果指标,它说明:原始报文没有在期望窗口内被确认。造成这个结果的原因可能有几类:
- 真实丢包:物理链路、交换设备、驱动、队列拥塞导致报文丢失。
- 时延抖动:报文没丢,但 ACK 回来得太晚,触发了超时重传。
- 接收端处理不过来:应用读不动、主机栈 backlog 累积、窗口缩小。
- 中间设备改写或限速:NAT、LB、防火墙、隧道封装等环节引入异常。
- 观察点偏差:抓包点位不对,看到的是镜像失真或 offload 影响后的“假象”。
所以,重传不是根因,重传是入口。 真正的价值在于:它能把“系统慢”快速收敛到“链路/主机栈/对端处理”这个范围里。
典型场景:哪些问题最容易出现重传
如果你在运维或 SRE 场景里遇到下面这些问题,优先看重传与丢包往往比盲目扩容更高效:
1)接口偶发超时,但应用层无明显报错
表现是:业务成功率整体没掉太多,但尾延迟突然拉长,且集中出现在跨机房、跨可用区、跨 VPC 调用上。这时抓包常能看到少量但持续的重传,叠加 RTT 抖动明显升高。
2)带宽没打满,但吞吐就是上不去
这类问题很典型。监控上看网卡只跑到 40%-50%,业务却觉得“链路像堵住了”。原因往往不是总带宽,而是微突发、队列长度、窗口大小、单连接拥塞控制等更细粒度因素。
3)新节点上线后,只有部分实例慢
如果只有一小批 Pod/主机慢,且重启后偶尔恢复,要高度怀疑节点层面的网卡配置、驱动版本、IRQ 绑核、容器网络路径或 MTU 不一致。
4)监控平台提示 5xx 上升,但数据库和应用都没打满
这时很多人先查 Nginx、应用线程池、DB 慢查询。没错,这些都该看,但如果错误主要是 upstream timeout、read timeout、连接断开,那么抓包与连接状态检查通常更快接近真相。
和传统方案的区别:为什么“只看资源监控”不够
很多团队的传统排障路径是:先看 CPU、内存、磁盘、总带宽,再看应用日志。如果这些指标没爆,就容易陷入“平台没问题,业务自己查”的互相甩锅。
但 抓包分析 + TCP 指标观察 与传统方案的边界很清楚:
- 传统资源监控擅长回答:机器有没有被打满。
- 抓包与连接分析擅长回答:请求为什么在链路上传得不顺。
也就是说,两者不是替代关系,而是分工关系。
适用边界
适合用抓包和重传分析的情况:
- 尾延迟升高但整体资源正常
- 某些节点、某些链路、某些时段明显更差
- 跨地域、跨机房、跨网络域调用异常
- LB、NAT、Service Mesh、容器网络引入复杂路径
- 用户反馈“偶发慢”“很难复现”
不适用边界
下面这些情况,不要把重传分析当第一优先级:
- 应用线程池、协程池、连接池已经明确耗尽
- 数据库慢查询或锁等待已实锤
- 单机 CPU 飙满导致用户态处理明显阻塞
- 业务代码有明确逻辑退化、死循环、缓存雪崩
一句话说清:如果问题明显发生在应用内部,先解应用;如果问题表现为“请求在线上跑不稳”,抓包和重传判断更有价值。
怎么选:看到重传后,先判断哪一类问题
真正高效的排查,不是“抓完包慢慢看”,而是先做问题归类。下面这 5 条判断标准,基本能覆盖大多数生产场景。
选型判断标准 / 排查清单
标准 1:重传是单点现象,还是链路共性
先回答两个问题:
- 是只有一台机器/一个 Pod 出现重传,还是整组服务都出现?
- 是同一目标地址都慢,还是多个目标都慢?
如果问题集中在少数节点,优先查:
- 网卡驱动与 offload 配置
- 容器网络插件
- 节点 MTU
- IRQ、RPS、RFS、队列配置
- 节点是否有丢包、丢中断、软中断异常
如果问题集中在同一条下游链路,优先查:
- 目标服务处理能力
- 中间 LB / NAT / 防火墙
- 跨地域线路质量
- 目标侧连接接收窗口
标准 2:是“真丢包”,还是“晚到确认”
不是所有重传都来自真实丢包。你需要结合 RTT、Dup ACK、Out-of-Order、窗口变化一起看。
经验上:
- 若 Dup ACK 明显增多,且某些序列号持续重复,偏向真实丢包。
- 若 RTT 抖动很大、ACK 只是回来得晚,偏向拥塞或接收端处理不及时。
- 若 Window Full / Zero Window 明显,偏向接收端来不及消费。
常用命令示例:
# 观察系统级 TCP 异常统计
netstat -s | egrep -i 'retrans|reset|timeout|listen|overflow'
# 查看内核 TCP 指标
ss -s
# 抓取与目标服务相关的流量
sudo tcpdump -i any host 10.10.20.15 and port 443 -w /tmp/api_latency.pcap
# 查看网卡错误、丢包、队列情况
ip -s link
ethtool -S eth0
如果你在 Wireshark 里只盯着 “TCP Retransmission” 这一列,很容易误判。要配合会话级时间线一起看。
标准 3:问题发生在发送端、接收端,还是中间设备
这一步决定你后续找谁。推荐顺序:
- 先在发送端抓包
- 再在接收端抓包
- 必要时在中间设备或镜像口补点位
如果发送端看到报文发出、接收端没看到,大概率在中间链路。 如果接收端已收到但处理慢、ACK 回得晚,问题在接收端或其应用。 如果两端都正常,但客户端仍慢,要怀疑更上游的 NAT、代理、出口网关。
标准 4:问题是否只发生在高峰期
只在高峰出现,通常比“全天都慢”更容易指向拥塞与队列问题。重点看:
- 突发连接数是否拉高
- SYN backlog 是否溢出
- accept 队列是否堆积
- 单机 PPS 是否过高
- 网卡 ring buffer 是否过小
- 限流、整形、QoS 是否在峰值时触发
例如:
# 查看监听队列与连接状态
ss -lnt
ss -ant | awk '{print $1}' | sort | uniq -c
# 查看软中断是否集中打到少数 CPU
cat /proc/interrupts | egrep 'eth|ens|enp'
# 查看 backlog 相关内核参数
sysctl net.core.somaxconn
sysctl net.ipv4.tcp_max_syn_backlog
标准 5:抓包结论能否和可观测性数据相互印证
只看包不看指标,容易做成“玄学排障”。更稳的做法是把抓包结果和指标体系对齐:
- 延迟升高时,是否同步出现重传、RTT 抖动、连接重置?
- 某节点慢时,是否同步出现软中断飙升、网卡 drop、容器转发异常?
- 某下游慢时,是否同步出现应用调用超时、LB 5xx、重试次数上升?
这就是为什么我更推荐“抓包 + 指标 + 连接状态”三件套,而不是孤立做任何一项。
一套可直接复用的实战排查流程
如果你现在就在处理生产事故,可以直接照这个顺序走:
第一步:先锁定异常范围
确认是全量慢,还是局部慢;是某链路慢,还是所有下游都慢。不要一上来就全网抓包。
第二步:对异常节点做最小化抓包
控制时间窗和过滤条件,只抓关键服务的五元组流量,避免包文件大到没法分析。
sudo tcpdump -i any host 10.10.20.15 and port 443 -c 5000 -w /tmp/short_window.pcap
第三步:同时采集主机侧指标
至少采集:
ip -s linkethtool -Sss -snetstat -s- CPU/softirq
- 容器网络转发统计
第四步:判断问题归属
按“发送端 / 接收端 / 中间链路”三分法归类,不要让所有团队一起盲查。
第五步:验证修复动作
常见修复动作包括:
- 调整网卡 ring buffer
- 优化 IRQ 绑核、RPS/RFS
- 关闭不合适的 offload 组合
- 校准 MTU
- 调整 backlog 与连接参数
- 优化连接复用与重试策略
- 在 LB / 网关层做更合理的健康检查与限流
修完后,必须重新看三件事:延迟是否恢复、重传是否下降、错误率是否同步下降。 只看某一个指标恢复,不算真正闭环。
运维工具怎么搭配更高效
很多人会问:抓包是不是太重?我平时更建议按这个组合来用:
- 监控平台(Prometheus / Grafana):发现范围和时间窗
- 连接工具(ss / netstat):判断连接状态与内核异常
- 网卡工具(ip / ethtool):确认设备层错误与队列状态
- 抓包工具(tcpdump / Wireshark):做最终证据链闭环
这套组合比单纯依赖 APM 更适合网络与运维侧问题,因为 APM 通常只能告诉你“调用慢了”,未必能告诉你“包为什么没顺利到”。
什么时候不该继续深挖抓包
也要克制。不是所有故障都值得抓一天包。
如果你已经确认:
- 慢查询压住了数据库
- 应用锁竞争严重
- 线程池耗尽
- 某个版本上线后逻辑退化明显
那就不要继续沉迷网络层证据了。工程上最忌讳的一种浪费,就是把所有问题都分析成“复杂链路波动”,听上去专业,实际上只是没抓到真正根因。
直接结论
TCP Retransmission 不是最终答案,而是排障入口。 当你看到接口偶发超时、尾延迟拉长、跨链路调用不稳,而资源监控又看不出明显异常时,优先从“重传 + RTT 抖动 + 连接状态 + 网卡统计”四件事入手,通常比盲目扩容更快、更省钱。
如果你只记住一句话,那就是:先判断是应用慢,还是链路不顺;先缩小范围,再抓包取证;不要把“看到重传”误当成根因,也不要在明显应用问题上过度网络化。
在实际落地里,像 AnaTraf 这类流量分析与链路观测产品,价值不在于替代抓包,而在于把“哪里慢、哪条链路抖、哪些会话异常”更快暴露出来,减少人肉翻日志和盲抓包的时间。对运维团队来说,能更快收敛问题范围,往往比堆更多监控图更有商业价值。