
网络不通、延迟偏高这类问题几乎每个做开发或者运维的人早晚都得碰上一回。最气人的不是服务挂了而是服务活得好好的就是响应慢半拍或者业务侧一会儿通一会儿断。ping网关通了、ping对端也通可应用层就像被什么东西卡住了一样。太多排查到最后发现问题根本不在应用代码而在链路上某一个不起眼的环节。这个时候tcpdump 就是最有用的底层取证工具——它能让你看到网络栈里最原始的数据包长什么样、谁丢了、谁重传了、谁时序乱了。下面这套流程是我做网络排查时反复用的方法把它拆成三步照着做基本能快速定位到“罪魁祸首”。1. 定位之前先把排查思路理清楚1.1 网络排查的基本盘先确认现象再选工具遇到网络问题第一反应别急着抓包。先问清楚几个问题是不通还是慢是所有节点都疼还是只有特定路径疼是持续性问题还是间歇性抽风我把“不通”和“慢”分开看完全不通通常指向链路断、路由问题、防火墙丢弃、ARP 解析失败这几类。通但慢更复杂一些可能是拥塞、丢包重传、TCP 窗口太小、MTU 过大导致分片丢失、对端处理能力不足。间歇性异常大比例是链路质量抖动、负载过高、缓存表项老化、或者某些定时任务引起的瞬时拥塞。工具选择也要跟着现象走。ping 只能验证三层连通性telnet/nc 只能验证端口通断curl 能看到应用层返回但这些工具都有一个共性它们只告诉你“结果不行”不会告诉你“哪个环节不行”。mtr 能测路径但它发的是 ICMP/UDP 探测包跟业务真实走的 TCP 流不一样。真正要还原业务数据包到底经历了什么只有抓包这一个办法。1.2 为什么是 tcpdump 而不是直接上 Wireshark很多人问过我这个事既然 Wireshark 图形界面看得那么清楚为什么还要用 tcpdump原因很现实。线上服务器大多没有图形环境你也不可能为了排查问题临时给生产机装桌面。tcpdump 是命令行工具几乎任何有网卡的 Linux 系统上都默认自带或者一条apt install/yum install就能装上。它能直接在出问题的机器上跑抓完生成.pcap文件再拿回本地用 Wireshark 打开做可视化分析。这已经是我习惯的标准工作流了。另一个关键点是tcpdump 基于 BPF伯克利包过滤器工作它旁路挂在网卡上监听经过的数据包不会修改数据、不会影响业务转发。抓包行为本身对网络的影响可以控制得很小前提是你别乱抓、别全量抓、别在核心链路上无脑长时间抓大流量。1.3 tcpdump 和 Wireshark 是怎么配合的我平时用的是这套组合拳在出问题的主机上用 tcpdump 抓包保存成文件。把抓到的文件拉到本地 Wireshark 打开用图形界面里的统计图、流的会话视图、专家提示信息辅助分析。如果手头只有命令行环境就用tshark或者capinfos做统计和分析。这个配合方式的好处在于抓包环节轻量、性能开销小分析环节直观、信息全面。尤其是当你看重传、看 TCP 时序、看往返时间 RTT 时Wireshark 的 IO 图、时间序图比瞪着眼睛盯 tcpdump 终端输出高效得多。归根结底tcpdump 负责“取证”Wireshark 负责“研判”两者缺一不可。2. 抓包这一步决定排查效率2.1 动手前的基线确认网卡、时间、规则抓包不是敲个tcpdump回车就行。我每次都会在抓包前花两分钟确认三件事省得抓回来才发现数据根本不对。第一网卡对不对。机器多网卡的情况太常见了物理网卡、虚拟网卡、bond 口错一个网卡啥都抓不到。如果不确定走哪张网卡可以用tcpdump -D列出所有可用网卡再配合ip route get 目标IP看实际出口走哪张。图省事就直接-i any但这个方式在某些环境下拿不到完整的链路层信息比如 VLAN tag 在有些驱动上会被剥掉。第二时间准不准。抓包分析特别依赖时间戳。排查延迟问题之前先确认系统时间是否准确date看一下偏差太大了先同步 NTP。如果两端同时抓包做对比分析更要确认两台机器时间一致不然后面的时序对比全是错的。第三规则要事先设计好。我建议你按下“抓什么”而不是“能抓到什么”来决定过滤规则。业务走的是 443 端口就只抓 443怀疑 DNS 有问题就只抓 53 端口怀疑某个 IP 异常就直接指定host。范围越精确文件越小噪声越少分析越快。2.2 必背的过滤表达式和参数tcpdump 的命令参数不复杂真正用得熟练全靠平时积累。我给你列几个我几乎每次都用的# 监听指定网卡不做 DNS 反解抓完整包长保存到文件 tcpdump -i eth0 -nn -s0 -w /tmp/capture.pcap # 抓取指定主机的所有流量 tcpdump -i eth0 -nn host 10.10.10.10 # 抓取指定端口限定协议和方向 tcpdump -i eth0 -nn tcp port 443 and src host 10.10.10.10 # 同时抓多个端口 tcpdump -i eth0 -nn tcp port 80 or tcp port 443 # 限定抓取 N 个包后自动停止 tcpdump -i eth0 -nn -c 1000 port 8080几个关键参数单独说下-nn不做域名反解、不显示服务名。反过来讲不加这个参数tcpdump 可能因为反解 DNS 导致输出很慢排障时千万别省这个。-s0抓全包。默认只抓前 96 字节或 128 字节的头部做协议分析凑合够但排查应用数据相关的问题比如确认包里的协议内容就必须要全包长。-e显示链路层信息看 MAC 地址和 VLAN 时用。排查 ARP、二层环路这类问题不加这个参数等于瞎抓。-vv / -vvv输出更详细信息能看到 TCP 选项、校验和之类的细节。-w写文件、-r读文件。生产环境抓包基本都是写文件谁会盯着终端看上百行的滚动输出呢。过滤语法是 BPF 表达式支持host、src host、dst host、port、src port、dst port、tcp、udp、icmp、less、greater这类关键词还能用and、or、not组合。注意顺序先写协议再写信址条件习惯上tcp port 443 and host 1.2.3.4这样的写法读起来更舒服。2.3 抓包时长和文件轮转的经验值新手最容易犯的错是把抓包开着放在那儿不管等发现问题去看磁盘满了或者文件大到工具都打不开。我一般根据地规摸设置抓包策略如果问题持续存在抓 30 秒到 1 分钟的包基本足够。如果是间歇性问题一次抓 5 到 10 分钟循环抓取多个文件直到捕获到异常窗口。文件大小控制在一个文件 100MB 到 200MB 以内超过这个量 Wireshark 打开会很吃力。结合-G按时间轮转和-W保留文件数参数实现自动轮转。举例每 60 秒生成一个新文件最多保留 10 个文件tcpdump -i eth0 -nn -s0 -G 60 -W 10 -w /tmp/monitor.pcap这样抓下来的文件会自动命名为 monitor.pcap、monitor.pcap1 这种按时间覆盖不影响业务也不会撑爆磁盘。3. 三步定位法实战拆解3.1 第一步按现象圈定抓包范围抓包范围怎么定直接决定后面的分析路径。我习惯先判断“从哪个视角看问题”如果客户端访问服务端失败先在服务端抓包看看请求有没有到达。如果到达了但客户端没收到响应再在客户端抓包看看回包有没有回来。如果两端都没问题还报不通那才需要中间链路介入比如在网关或交换机镜像口抓包。有条件的情况下强烈建议同时在两端抓包时间对齐后做对比分析这是定位网络问题最有说服力的方式。两边都好端端数据就是没穿过中间网段的时候你就知道不是机制性故障而是网络路径上的问题。抓包数量的控制也有讲究。不要一上来全量抓包那会让文件以每秒几十 MB 的速度增长。根据现象缩小范围端口不通就抓该端口的 TCP 流量丢包明显就抓 ICMP怀疑 DNS 就抓 UDP 53。3.2 第二步从包特征反推问题点抓到包之后看什么很关键。我习惯按照这个顺序逐步筛查第一道看 TCP 握手有没有完成。客户端发 SYN服务端回 SYN-ACK客户端再回 ACK这三步缺了哪一步问题就在那一环。比如 SYN 发了 N 次服务端就是没响应要么服务端没监听要么防火墙把包丢了如果服务端回了 SYN-ACK客户端却一直重发 SYN大概率是回程路径上回包丢了。第二道看有没有重传和重复 ACK。TCP 是靠“确认”保证可靠性的。如果一个包发出去后超时没收到 ACK发送端会重传传一次说明有瞬时丢包频繁重传就说明链路质量有问题。通过 tcpdump 抓到的重传包数量能估算实际丢包率。第三道看延迟的构成。用一个连接的三次握手时间举例从 SYN 包发出到收到 SYN-ACK 的间隔就是一次 RTT把它跟正常基线做对比能大概看出是网络路径长了还是对端处理慢了。如果来回要 100ms 以上而你的业务本来应该在同机房跑那肯定是不正常的。第四道看乱序。TCP 会尽量按序号有序递交。如果抓包里出现大量乱序包、乱序到达的 ACK通常说明路径上存在多条链路负载均衡或者缓冲抖动。下面的速查表是我自己整理的分享你直接抄包特征大概率问题方向SYN 频繁重传无响应服务端未监听、防火墙过滤、SYN 包被丢SYN-ACK 发出但客户端重传 SYN回程路由异常、回包被防火墙拦截大量 TCP 重传Retransmission链路丢包、接收窗口耗尽、带宽拥塞大量 Dup ACK丢包触发快速重传、乱序触发重复确认包负载整齐接近 1500 字节时重传MTU 设置不合理可能导致IP分片丢失ICMP fragmentation needed 频繁MTU 不匹配路径上某些设备不支持大包出现大量 ARP 请求网关 MAC 解析异常、ARP 表震荡RST 包端口未监听、应用主动重置、防火墙干扰3.3 第三步交叉验证并确认罪魁祸首包特征只能告诉你“有问题”要确认“是什么问题”还得做交叉验证。我的做法是抓包证据 系统状态 配置核查三者比对。举例来说服务端抓包看到 SYN 到达但应用没有回包那就去查服务进程还在不在、监听端口有没有被占用ss -lntp | grep 443如果监听还在但又没回包那可能是服务端 accept 队列满了或者内核 SYN cookies 触发后的行为异常这时就看netstat -s里的相关计数。如果是路由层面的问题ip route get 目标IP会告诉你内核到底选哪条路径走。加上iptables -L -n -v看计数器能判断包是不是在防火墙规则里被 DROP 了。这里有个小技巧本来iptables每条规则 DROP 的计数都可能是 0但等异常窗口过去再看如果某一条的包计数一直在涨那基本就是它在捣鬼。抓包结论不是孤证。我的习惯是至少要有一个系统层指标、一个抓包特征、一个配置事实互相对应才敢认定问题根源。4. 典型场景实录三个真实案例4.1 案例一TCP 重传率飙升问题出在 MTU一次线上故障业务反馈跨机房数据同步慢。我上服务器看了下ping对端 IP 正常延迟 5ms 左右但 TCP 传大文件只有正常速度的三分之一。在两端分别抓包。客户端抓到的包几乎每 3 到 5 个就有一个重传服务端抓到的包却看到大量重复的 ACK。进一步看包大小发现数据包负载全是 1460 字节左右接近以太网 1500 字节 MTU 的上限。结合之前链路中有一个奇怪的网段跳数异常我怀疑路径上某个设备的 MTU 比较小。验证方式本地ping -M do -s 1472 对端1472 负载加 28 字节 IPICMP 头正好 1500目标 IP 能通。但用同样的方法测试路径上某些中转 IP返回Fragmentation needed的错误。说明问题在这条中转链路上。原来客户端和服务端都是标准 MTU但中间有一个隧道设备把 MTU 限制到了 1400。大包到那儿被分片或丢弃TCP 通过重传恢复速度直线下降。把两端网卡 MTU 调整后问题立刻消失。这个案例里不抓包根本看不出来重传模式跟包大小强相关只会傻傻认为是线路带宽不够。4.2 案例二间歇性延迟尖刺元凶是 ARP 震荡某应用频繁出现“偶发延迟”每次 3 到 5 秒之后自己恢复。ping 网关一直正常流量没有断。在应用的服务器和应用网关两侧同时抓包。平时抓到的都是正常包没有异常。等了七八分钟终于抓到了一次尖刺客户端发出 SYN 后隔了 800 毫秒才收到 SYN-ACK。抓包文件里这段时间前后混了一堆 ARP 请求——客户端在反复请求网关的 MAC 地址。顺着 ARP 泛滥往下追发现是网关的某个接口做了热备切换主备切换时虚拟 MAC 地址发生了漂移。客户端 ARP 表还没更新过来发的 ARP 请求要么没被响应要么被滞后处理了连接建立出现了短暂的“黑洞期”。这种问题ping 根本发现不了因为 ping 用的是 ICMPICMP 走的是另一套交互逻辑应用侧 TCP 建连却对这个抖动非常敏感。抓包把 SY N 到 SYN-ACK 间隔和 ARP 请求的时间线放在一起对比才真正锁定问题。4.3 案例三SYN 到了不回包防火墙规则在捣鬼某服务升级后外部客户端连不上新端口。服务端ss -lntp确认端口已监听客户端 telnet 不通。服务器端抓包发现客户端的 SYN 一个不少全部到达。诡异的是服务器内核对 SYN 没有做任何响应。继续查内核参数net.ipv4.tcp_max_syn_backlog、半连接队列没有溢出netstat -s也没看到 SYN 被丢弃的计数。此时抓包窗口正好在防火墙后面把防火墙规则倒出来看发现有一条链上顺序里把新端口对应的目标地址写进了 DROP 规则且这条规则排在了 ACCEPT 之前。IP 层的数据包到达后得先过防火墙规则检查被 DROP 了之后TCP 协议栈压根没有机会看到这个包。那为什么抓包能抓到 SYN因为抓包点在防火墙前面。这件事给我的教训就是先确认抓包点在数据路径的哪一段不要只看到数据包到了就下结论要确认它有没有穿过整个协议栈。5. 常见问题与避坑实录5.1 抓不到包先检查这四处网卡抓错了用-D列清楚再选。过滤规则写太严了比如你只抓port 443但业务实际用的是 8443就什么都没了。报文被 offload 功能处理了某些网卡开启 GRO、LRO 之后小包会被合并成大包你抓到的可能不是原始形态。抓包权限不足某些环境中 tcpdump 需要 root 或 CAP_NET_RAW 权限普通用户可能拿不到包。容器场景下更要注意在宿主机上抓包不一定能看到容器内的完整流量因为容器有自己的网络命名空间。要在容器所在的 netns 里抓包或者直接在容器内部跑 tcpdump如果镜像里装了的话。5.2 抓出来的包看不懂怎么办我看过不少人抓包时很兴奋抓到文件后打开 Wireshark 就傻了全是乱序、重传、Dup ACK不知道从哪看起。我的建议分三步走先用capinfos看文件基本信息抓包时长、平均流量、包个数。再用 Wireshark 的“统计 - 会话”和“统计 - IO 图”看宏观趋势。IO 图能直观看到哪个时段流量异常。最后才聚焦到可疑连接上右键“追踪流 - TCP 流”看整个交互过程。如果是纯命令行环境可以用 tshark 快速统计重传次数tshark -r capture.pcap -q -z io,stat,1 tshark -r capture.pcap -Y tcp.analysis.retransmission | wc -l5.3 别忘了在追问题前先看时间戳tcpdump 默认输出带时间戳但那个时间戳是相对开机时间还是绝对时间看你加不加参数。排查延迟问题时我强烈建议加-tttt让每条记录显示完整的日期和绝对时间。分析时还要注意抓包文件里的时间戳反映的是抓包机器本地时钟不是网络时间。如果两端联动分析一定确保系统时间已同步。我曾经在一次排查里把时钟偏差当成链路延迟折腾了大半天才发现是两台服务器时间差了 30 秒做分析时牛头不对马嘴。5.4 别让抓包本身成为“帮凶”生产环境抓包要谨慎。抓包工具虽然不修改数据但长时间全量抓大流量会把 CPU 和内存吃得很高缓冲区满后丢包率还会上升。抓包期间的性能下降可能会让原本不那么明显的问题反而放大。我认为比较稳妥的操作是先小流量验证抓包可行再放宽到目标流量限制文件大小和抓包时长抓完立即停止并分析不要一直挂在那里。如果遇到突发大流量宁可丢弃部分抓包数据也不要让主机因为抓包而无法服务用户请求。写在最后的体会排查网络问题这些年最大的体会是定位问题靠逻辑确证问题靠抓包。tcpdump 不会直接告诉你“网关坏了”或者“防火墙拦了”但它会诚实地把每一个经过的包展示给你看。你只要掌握从现象出发、从包特征反推、用系统状态交叉验证这条思路大多数疑难杂症都能找到明确的答案。再补充一个我常用的习惯抓包文件命名时记下一行备注说明时间、地点、抓到什么现象隔几天再翻文件时自己也能看懂当初为什么抓它。这一步看似不起眼但在复杂问题的复盘阶段能省下大量时间。