4. 网络层面排查:tcpdump抓包与Wireshark分析
接口超时了,服务端日志看了一圈,客户端日志也翻了个遍,就是找不到原因。
这时候,我一般会直接祭出抓包工具。为什么?因为网络是诚实的。应用层说“我发了”,网络层可能根本没出去;客户端说“收到响应了”,可能只是收到了一个RST包。
说白了,抓包就是用上帝视角看一次请求的完整生命周期。本节我们就聊聊tcpdump和Wireshark怎么用,以及在超时场景下到底要看什么。
4.1 抓包前的接入准备
很多人一上来就tcpdump,抓完了发现文件太大,或者根本没抓到想要的包。我自己出过这个糗,所以先说两句准备工作。
抓包位置怎么选?
- 客户端出口:查客户端是否真的发出了请求,以及请求内容是否正确。
- 服务端入口:查服务端是否真的收到了包,以及响应是否完整发出。
- 中间链路:查防火墙、负载均衡、网关是否丢包或篡改报文。
我建议大家优先在客户端出口和服务端入口同时抓。为什么?因为能对比。客户端发了但服务端没收到,那就是中间链路的问题。两边都收到了但客户端还超时,那就是应用层或系统层的问题。
4.2 端口镜像与流量复制
在生产环境抓包,最怕的就是影响业务。你想想,一个高并发的服务,你对着它的网卡一顿猛抓,说不定CPU就上去了,延迟也跟着涨。
所以我推荐两个常用方案:
| 方案 | 原理 | 适用场景 | 风险 |
|---|---|---|---|
| 端口镜像 | 交换机将指定端口流量复制一份到监控口 | IDC/机房环境,有交换机管理权限 | 低,不影响原流量 |
| iptables TEE | 在Linux主机上用iptables规则复制流量 | 云环境或没有交换机权限时 | 中,会增加CPU开销 |
4.3 tcpdump实战抓包
准备工作做好了,开始动手。tcpdump命令不长,但参数得选对。我曾经因为没加 -s 0,导致抓到的包被截断,查了半天白查。
常用的抓包命令模板:
# 在客户端抓,只抓目标端口为8080的包,保存到文件
tcpdump -i eth0 -s 0 -w /tmp/client.pcap host 10.0.0.1 and port 8080
# 在服务端抓,抓来自客户端的包
tcpdump -i eth0 -s 0 -w /tmp/server.pcap host 10.0.0.2 and port 8080
# 不存文件,直接看简要信息(常用于快速确认)
tcpdump -i eth0 -nn host 10.0.0.1 and port 8080
几个关键参数说明:
-i eth0:指定网卡。我见过有人在多网卡机器上忘指定,结果抓了空的网卡。-s 0:抓取完整包,不截断。默认只抓前96字节,对分析应用层数据不够用。-w file.pcap:写到文件,后续用Wireshark分析。-nn:不解析主机名和端口号,避免DNS查询干扰。
什么时候加过滤条件? 高流量场景下,不加过滤等于自杀。抓回来的全是广播包,有用的就那么几个。我建议始终加 host 和 port 过滤。
4.4 Wireshark分析技巧
抓回来的pcap文件,用Wireshark打开。说句实话,Wireshark界面信息量太大,新手容易看懵。别急,我们只盯三个核心指标:重传、窗口、握手时间。
- TCP重传:说明对方没收到ACK,可能是丢包,也可能是对端处理慢。
- 零窗口:说明接收端缓冲区满了,无法再接收数据。
- 三次握手时间:如果SYN到SYN-ACK耗时超过1秒,大概率是网络延迟或服务端全连接队列满。
我的分析步骤一般是:
- 打开抓包文件,用
ip.addr == 10.0.0.1 && tcp.port == 8080过滤目标流。 - 点击“Statistics” - “TCP Stream” 查看应用层数据是否完整。
- 在“Expert Info”里看有多少重传和零窗口事件。
- 找每一个重传包的差距时间,一般是200ms、400ms、800ms……如果呈指数增长,说明是标准超时重传。如果间隔固定,说明是应用层超时。
举个例子: 有次排查一个接口偶发超时,服务端日志显示处理只用了10ms,但客户端就是超时了。我同时在两端抓包,发现客户端发出了POST请求,但服务端根本没收全。仔细看包,中间被切成了两个TCP段,第二个段没到。那就是中间防火墙把大包丢了。改MTU问题解决。
4.5 核心排查流程图
我把整个网络排查逻辑梳理成了一张图。你在实战中可以按这个流程走,基本不会漏掉关键点。
4.6 常见超时模式与对应根因
我总结了几种最常见的超时模式。你在Wireshark里看到这些特征,基本就能锁定问题方向。
| Wireshark现象 | 可能的根因 | 建议排查方向 |
|---|---|---|
| 大量TCP重传,间隔指数增长 | 网络丢包、中间设备丢包 | 检查MTU设置、防火墙策略、链路质量 |
| 零窗口频现,接收窗口为0 | 服务端处理慢,应用层阻塞 | 检查服务端线程池、数据库连接池、GC停顿 |
| SYN发出后1秒才有SYN-ACK | 服务端全连接队列满,或客户端SYN被限速 | 调整net.core.somaxconn,增加backlog |
| 请求发出后迟迟收不到最后一个ACK | 客户端socket阻塞,或内核缓冲区满 | 检查客户端发送缓冲区大小、应用层写入逻辑 |
4.7 高频抓包参数参考
最后,把我平时最常用的一些抓包参数整理成一张表,方便你直接拷贝修改。
| 场景 | 命令模板 | 说明 |
|---|---|---|
| 按目标IP和端口抓 | tcpdump -i eth0 -s 0 -w /tmp/a.pcap host 10.0.0.1 and port 8080 |
最常用,建议优先使用 |
| 抓两台主机之间的流量 | tcpdump -i eth0 host 10.0.0.1 and host 10.0.0.2 |
适合排查点对点问题 |
| 抓大包(>1000字节) | tcpdump -i eth0 -s 0 greater 1000 |
适合排查MTU问题 |
| 抓SYN包 | tcpdump -i eth0 -s 0 'tcp[tcpflags] & (tcp-syn) != 0' |
看连接建立是否正常 |
好,网络排查这块我们基本说清楚了。tcpdump抓包加上Wireshark分析,这组合拳打好了,接口超时在网络层的问题基本跑不掉。接下来,你会看到一个具体的实战报告是怎么写的。继续往下翻就行。