抓包,就是网络世界的“行车记录仪”:一次 tcpdump 实战找回“丢失”的响应

📅 2026/7/2 13:25:56
抓包,就是网络世界的“行车记录仪”:一次 tcpdump 实战找回“丢失”的响应
你调用一个第三方接口明明收到了响应但 Java 代码一直阻塞直到超时。你看代码、看日志、看配置全都没问题。你怀疑网络但 ping 通了端口也是开的。你陷入了僵局。这时候你需要 tcpdump——抓包就是网络世界的“行车记录仪”它能回放每一帧数据告诉你真相。大家好我是Evan一个靠 tcpdump 抓包抓到过对方网关“悄悄丢包”的 JavaAI 学生。今天我用一次真实的线上排障案例带你从零上手 tcpdump教你用 Wireshark 分析TCP 重传、零窗口、RST 连接等异常信号并学会区分“应用层没响应”和“网络层没送到”。读完这篇你再遇到“请求已发、响应不回”手里就多了一把真正的“照妖镜”。 写在前面在智荟Agent项目的上线前夕我们发现调用某外部大模型 API 时大约有 5% 的请求会超时。日志显示“连接超时”但对方的监控面板显示他们已经返回了 200。我们查了自己代码的线程池、连接池、GC全都没问题。最后我抱着试试看的心态在服务器上执行了tcpdump -i eth0 host api.llm.com -w bug.pcap把抓到的包下载到本地用 Wireshark 打开——那一刻真相大白对方的网关在我们发完请求后直接回了一个 TCP RST重置连接包但我们的 HTTP 客户端根本没读到响应体直接抛了超时异常。从那以后tcpdump 成了我排网络疑难杂症的“首选武器。一、tcpdump 基础30 秒就能上手1.1 最常用的命令模板bash tcpdump -i any host 192.168.1.100 -w dump.pcap-i any监听所有网卡host 192.168.1.100只抓与这个 IP 通信的包-w dump.pcap写入文件方便用 Wireshark 分析1.2 常用抓包选项选项含义-i eth0指定网卡host 8.8.8.8按 IP 过滤port 8080按端口过滤src host X只抓源 IP 是 X 的包dst host X只抓目标 IP 是 X 的包-s 0抓取完整数据包不截断-n不进行 DNS 解析加快速度-c 100只抓 100 个包后自动停止-w file.pcap写入文件-r file.pcap读取已有抓包文件二、Wireshark 读包你要找的 4 种“信号”把dump.pcap下载到本地用 Wireshark 打开。你要看的是这四种信号2.1 正常的三次握手text SYN → SYNACK → ACK如果抓包里没有看到SYNACK说明对方根本没收到请求——防火墙拦截了或者 IP/端口错了。2.2 数据流的确认ACK你的请求发出后对方应该回复ACK表示“我收到了你的数据”。如果只看到你的请求包没看到任何ACK说明数据包在途中被丢弃了。2.3 标志位重传RetransmissionWireshark 会把重传包标记为红色TCP Retransmission。如果看到大量重传说明网络存在丢包或拥塞。2.4 标志位零窗口Zero WindowWireshark 标记为“TCP Zero Window”。表示对方的接收缓冲区满了无法再接收数据——你的应用还在傻等响应但对方已经“撑”住了。2.5 标志位RST 包连接重置Wireshark 标记为“RST”。这是最关键的“暗号”表示对方强行关闭了连接。常见原因对方应用进程崩溃或主动终止了连接防火墙检测到异常流量直接丢掉连接对方认为你的请求不符合协议规范比如 HTTP 格式错误对方配置了“长连接超时”主动切断了空闲连接三、真实案例“请求已发响应不回”的真相3.1 场景重现第三方 APIhttps://api.partner.com/v1/payment我们用RestTemplate发 POST 请求请求超时设置 10s但几乎每次到 5s 就报ReadTimeout对方监控显示他们收到了请求也返回了 200耗时仅 200ms3.2 抓包分析步骤步骤 1定位连接步骤 2复现问题执行一次请求等待超时后停掉抓包。步骤 3Wireshark 查看流用tcp.stream eq 0筛选出整个 TCP 流。步骤 4发现真相Wireshark 显示如下时序text 14:23:01.123 Client → Server: POST /v1/payment (HTTP) 14:23:01.125 Server → Client: ACK (确认收到请求) 14:23:01.400 Server → Client: [TCP RST] (重置连接目标端口 50820)关键结论对方收到了请求看到了 ACK对方没有发出 HTTP 响应没有HTTP/1.1 200报文对方直接发了一个RST包但对方的业务日志说“返回了 200”真相对方的七层负载均衡在收到请求后判定请求头不符合他们的“安全校验”直接在 TCP 层发了 RST但应用层日志的“返回 200”是从负载均衡网关日志里来的而不是后端业务服务器的真实日志。四、tcpdump 的进阶技巧4.1 抓取 HTTP 请求体方便排查协议错误bash # 抓取 HTTP 请求包打印出其中的内容 tcpdump -i eth0 -A -s 0 tcp port 8080 and (((ip[2:2] - ((ip[0]0xf)2)) - ((tcp[12]0xf0)2)) ! 0)4.2 按时间段分割抓包文件bash tcpdump -i eth0 -G 60 -w %Y%m%d_%H%M%S.pcap每 60 秒生成一个新文件适合长期监控。4.3 结合tcpdump和nc做连通性测试bash # 抓包 发一个简单请求 echo -e GET /health HTTP/1.0\r\n\r\n | nc -w 5 192.168.1.100 8080 总结故障现象可能原因tcpdump 信号请求发出对方无任何回包网络不可达 / 防火墙拦截只看到 SYN没有 SYNACK请求发出对方回了 ACK但无响应体对方应用层处理异常只有 ACK没有应用层数据收到 RST 包对方主动关闭连接红色 RST 标记收到响应体但 Java 仍超时响应体不完整 / 分片丢失TCP 重传 未收全包响应很慢对方接收窗口为 0Zero Window 标记核心结论tcpdump 是网络排障的“真相还原器”它能帮你跳过所有日志的“谎言”。遇到“请求已发、响应不回”时先用 tcpdump 确认网络层是否正常再查应用层。RST 包是最关键的排查信号——它告诉你“对方在应用层之外就拒绝了你的连接”。思考题你在生产环境排查一个偶发的“响应超时”问题。该服务每天处理 10 万请求只有不到 0.1% 的超时。你怀疑是网络问题但用户侧和服务器侧的监控都显示网络延迟正常。你决定在服务端抓包 24 小时但 24 小时的 pcap 文件可能高达几百 GB无法直接保存到磁盘。问题你会用什么方法既能持续抓包又能及时“捕获”到那 0.1% 的异常 TCP 行为而不浪费大量磁盘空间提示考虑tcpdump的环形缓冲区、-C/-G参数、BPF 过滤表达式或结合ngrep欢迎在评论区留下你的方案 —— 下一篇我会聊聊“网卡软中断与 CPU 飙升为什么服务器si占用高达 80%”