开放问答
抓包看到 TCP Retransmission 后,如何 5 分钟区分真丢包、乱序假重传与接收窗口压小?
该问题的正文、回答与评论。
提问者 顾知远-314 · 状态 open
TCP重传抓包网络排障可观测性
【背景】 我负责一条跨机房 gRPC 长连接链路:A 机房(10.10.x.0/24,3 台业务机,Linux 5.15)→ 运营商专线(双上联,ToR 是 Cisco N9K,25G 光模块)→ B 机房(10.20.x.0/24)。业务是同步 RPC,P99 目标 < 300ms。最近 3 周偶发约 1% 的调用超时,单次卡顿 0.5~2s,重试一次就好,无持续故障。
【现象】
- ping RTT 稳定 18ms,无毛刺;
- iperf3 单向跑满 10G,丢包 0;
- 交换机 counter(ifInDiscards / ifOutErrors / 光模块 FEC 误码)都干净;
- 但主机侧 nstat -az 看到 TCPLostRetransmit 在涨;
- tcpdump 抓到 [TCP Retransmission],单连接偶发,重传 1~3 个段就恢复。
【已尝试的排查与结果】
- tcpdump -i eth0 -nn 'host 对端IP and port 50051' 抓了 5 元组,确认了 retransmission,但我目前只看到"有重传",没系统判读 SACK 块 / [TCP Out-Of-Order] / [TCP ZeroWindow];
- ss -tinm 看过一次,cwnd/ssthresh/rto 没留时间线,事后对不上;
- nstat 只看了 TCPLostRetransmit,没和 TCPRetransFail、TCPSACKReorder、TCPRcvQDrop、TCPInErrs 一起对照;
- 还没在发送端 / 接收端两侧同时抓包对齐时间戳。
【我现在真的卡住的点】 看到 retransmission 之后,我分不清到底是下面哪一类: (a) 真·链路丢包(某段光纤 / 队列溢出); (b) 乱序导致的"假重传"(其实没丢,只是乱序 + 接收端 RACK/SACK 触发重传); (c) 接收端应用没及时 read → 接收队列满 → 窗口压小 → 发送端停发,被误判成"网络卡"; (d) 接收端 zero window 后的 window 探测包。
【期望得到的答案形态】 一个"抓到 retransmission 后 5 分钟归因"的可复现判据清单,最好按判读顺序给出:
- tcpdump 该加哪些过滤 / 该重点看哪些字段(SACK 块、[Out-Of-Order]、[ZeroWindow]、seq/ack 关系);
- nstat 里哪几个计数要一起看、怎么组合判定(例如 TCPSACKReorder 高→偏乱序;TCPRcvQDrop 高→偏接收队列;TCPLostRetransmit 高而 Reorder 低→偏真丢);
- ss -tinm 里 cwnd/ssthresh/rto/backlog 怎么读、发送端和接收端怎么对齐时间线;
- 如果怀疑 (c),怎么从应用侧(read 频率 / SO_RCVBUF / epoll 唤醒)验证。 最好附一两条可直接跑的命令。我不需要"推荐某款工具",我需要的是把上面四类判据区分开、能照着跑的顺序。
评论
暂无评论。