网络案件的证据分散在内核计数器、连接状态和抓包三个层面。本节给出一套从粗到细的侦查顺序:重传率定方向、连接状态分布定位、缓冲区与抓包定罪,并用一个真实推理链演示"看起来像网络问题"最后定罪为缓冲区不足的全过程。
# 两次采样求差值才是速率 nstat -az | grep -i retrans ss -s # 连接状态汇总
判读口径:TCP 重传比例(重传段数 / 发出总段数)超过 1% 就值得关注,超过 5% 是明确的网络案件。重传高说明丢包,丢包的直接后果是 TCP 退避——拥塞窗口减半,吞吐塌方。所以丢包对吞吐的杀伤是乘性的:1% 的丢包在某些场景能吃掉一半带宽。

这张图解释了大量"千兆网卡只有几 MB/s"的悬案:瓶颈不在带宽在窗口。带宽是公路宽度,窗口 × RTT 是你被允许同时在路上的车数——路再宽,同时只能有 64KB 在路上,速率就锁死了。
ss -tan state established | wc -l ss -tan | awk '{print $1}' | sort | uniq -c
关注异常状态的堆积:
CLOSE-WAIT:对端关了连接,本端应用没调用 close——代码级 bug 的指纹,连接泄漏;SYN-RECV:半连接堆积,疑似 SYN 攻击或 accept 队列打满;send-q 常年非零且增长:对端消费不动或网络拥塞,发送缓冲区成为蓄水池。配合内核计数器看丢弃点:
nstat -az | grep -Ei 'drop|overflow|listen' # TcpExtListenDrops / TcpExtListenOverflows:accept 队列溢出 # TcpExtTCPRcvCollapsed:接收缓冲区压力
ListenOverflows 非 zero 且增长,说明三次握手完成了但应用 accept 不及——不是网络的锅,是应用的 accept 循环或线程池堵了。
收发缓冲区的检查:
ss -tinm dst 10.2.0.5 # cwnd:拥塞窗口 rto:重传超时 rtt/rttvar:往返估计 # skmem:(r0,rb<接收上限>,t0,tb<发送上限>...)
看 cwnd 是否被压小(重传退避的结果)、RTT 估计多少、缓冲区上限是否已顶到。
抓包是终审证据,但生产环境代价高。低开销的替代是 eBPF 的 TCP 事件追踪:
tcpretrans-bpfcc # 每次重传的时间、连接四元组、当时状态 tcplife-bpfcc # 每条连接的寿命与吞吐
tcpretrans 的输出长这样:
TIME PID COMM LADDR LPORT RADDR RPORT STATE 10:02:11 3121 api 10.1.0.8 44312 10.2.0.5 3306 ESTABLISHED
重传全部集中在连数据库的连接上——数据库侧或路径上的问题,与应用的公网出口无关。四元组一出来,责任边界就划清了。
跨机房文件同步只有 2 MB/s,双方都说是对方的网络。推理:
nstat 重传率 < 0.1%,链路丢包排除;ping RTT 32ms,物理距离决定,改不了;ss -ti 看到发送窗口顶在约 64KB;没有一处需要"换网络",30 分钟的配置调整解决了缠斗两周的悬案。
网络慢的指控要用分段计时坐实。在连接两端同时抓握手与首包,把延迟拆成"建连前"(DNS、SYM 队列)、"建连中"(RTT、重传)、"建连后"(服务处理、Nagle/缓冲)。一次性采集:
# 客户端侧 dig +stats api.example.com # DNS 解析耗时与缓存命中 ss -tni dst 10.2.3.4 | head -5 # rtt/cwnd/retrans 现值 nstat -az | egrep 'RetransSegs|OutSegs|EstabResets' # 服务端侧 ss -tln sport = :443 # 送入队列 (Recv-Q) 是否堆积 cat /proc/sys/net/core/somaxconn # accept 队列上限
RetransSegs/OutSegs 超过 1–2% 即可在案卷里写"传输层劣化";客户端 rtt 正常但服务端 Recv-Q 堆积,责任在应用 accept 速度而非网络。
丢包常被当成网络问题结案,实际不少是缓冲区配置问题:netdev_max_backlog 打满时内核直接丢包,表现为"网卡没坏但丢";UDP 接收缓冲不足时 UdpRcvbufErrors 增长,应用层只看到"收不全"。用 nstat -az | egrep 'Drop|Overflow' 一次列出所有丢弃点计数,哪一个在涨,哪一个就是瓶颈,而不是先怀疑交换机。定位到具体计数器后再调缓冲或提高消费速率,每一步都有前后对照,避免"全网卡参数抄一遍"式的雾里调参。
最后补一条跨机房链路的定量思路:物理距离决定 RTT 下限(光在光纤中约 5µs/km,单程),跨城 1000km 的 RTT 下限约 10ms,任何低于物理下限的测量结果都说明测量点选错了。应用层看到的 RTT 等于物理 RTT 加上两端的排队与处理,分段测量后各段之和应等于端到端值,对不上的部分就是未覆盖的环节(负载均衡、TLS 握手、代理)。把这套"守恒校验"用在跨机房迁移评估上,可以提前发现"多了一跳没规划的内网穿透"这类设计问题,而不是等上线后用 P99 事故来发现。