“TCP 重传变多”只说明发送方没有按预期收到确认,不说明包究竟在哪一层丢了。包可能在网卡 RX/TX ring、驱动、softnet backlog、协议栈校验、socket 队列、应用处理或链路对端消失。有效排障的顺序是先用计数器缩小层级,再用 tracepoint 或 kprobe 捕获少量、可关联的证据,最后将五元组、时间、CPU 和调用路径串起来。
先按层收集“不会改变时序”的证据
网卡驱动统计可提示 RX/TX ring 是否溢出;/proc/net/softnet_stat 可提示协议栈接收处理是否来不及;ss -ti、netstat -s 或 nstat 可展示 TCP 重传、listen overflow、socket 错误等。先做两次快照并比较增量,才知道哪一个计数正在增长。
1 | ethtool -S eth0 |
不同驱动和内核暴露的字段不同,分析前应保存原始输出与时间。把所有计数拼成一个“大总数”通常会失去定位价值。
tracepoint 优先,kprobe 用于补洞
tracepoint 是内核显式提供的观测事件,语义相对稳定,例如 TCP 重传、skb 释放、调度和 IRQ 事件;它更适合长期脚本。kprobe 可以挂到任意可探测函数,灵活但会受函数内联、重命名和内核版本影响,适合 tracepoint 不够时的短期定位。
1 | 计数器发现 softnet 丢弃增长 |
高流量路径上的跟踪本身会产生压力。必须限制 CPU、PID、端口、采样窗口或采样率,先在可复现小流量场景验证,再进入生产问题窗口。
最终证据应能回答什么
一条好的丢包报告不是“抓到一个 kprobe”,而是能够说明:哪个层的哪个计数增长、增长发生在何时/哪个 CPU、关联的流是什么、为什么该层会丢,以及修复后同一负载下计数和业务结果怎样变化。这样 TCP 重传从一个模糊症状,变成可验证的因果链。