这个场景解决什么
「客户端说发了、服务端说没收到」这类争议,只有抓包能给出裁判结论。做法是在链路两端同时抓:客户端抓出口,服务端抓入口,按时间戳对齐后对比同一时刻有没有 SYN 到达、有没有响应返回。根据有无 SYN、有无 SYN-ACK、有无 RST 三种组合,就能把责任界定到网络中间、本机防火墙或应用层。
基本信息
| 适用场景 | 请求丢失、连接超时、跨层定责 |
|---|---|
| 核心工具 | tcpdump 双向抓包,配合 ss 查看本机监听与队列状态 |
| 抓包位置 | 客户端出口、服务端入口;容器环境在容器网络命名空间或节点出口抓 |
| 要点 | 两端一起抓、加过滤表达式、限制包数,用绝对时间戳对齐 |
典型使用场景
- 连接超时定责:判断 SYN 是否到达服务端,区分网络拦截与后端问题
- 安全组与防火墙验证:确认放行规则是否真的生效,而不是只看规则列表
- 服务未监听排查:服务端抓到 SYN 但没有响应,说明本机没有进程在监听
- 偶发丢包取证:结合两侧抓包判断是单向丢包还是应用处理超时
- 对外工单举证:给云厂商或运营商提供双向抓包时间线,沟通效率显著提高
双向抓包
双向抓包
# 服务端(先启动,避免漏掉开头)
tcpdump -i any -nn -tt -c 50 'tcp port 8080 and host 10.0.0.5'
# 客户端(随后发起请求)
curl -sS --max-time 5 http://10.0.0.9:8080/health
tcpdump -i any -nn -tt -c 50 'tcp port 8080 and host 10.0.0.9'
# 需要事后分析时先落盘
tcpdump -i any -nn -s 0 -w /tmp/8080.pcap 'tcp port 8080'结果判读与旁证
结果判读与旁证
# SYN 到达且 SYN-ACK 返回:网络通,问题在应用层
# 客户端只见 SYN 重传、服务端没有对应记录:中间被拦(防火墙/安全组/NAT)
# 服务端抓到 SYN 但无响应:本机防火墙或没有进程监听
ss -lnt | grep :8080 # 看是否真有监听
ss -lnt 'sport = :8080' # 关注 Send-Q 是否为 0(全连接队列是否够用)
iptables -S | grep 8080; nft list ruleset 2>/dev/null | head # 本机规则核对
journalctl -k --since '5 min ago' | grep -i drop # 内核是否在丢包现象与结论对照
| 客户端看到 | 服务端看到 | 结论 |
|---|---|---|
| SYN 重传 | 无任何记录 | 中间链路拦截:安全组、边界防火墙或 NAT |
| SYN 重传 | 收到 SYN | 服务端回程被拦,或响应被路径丢弃 |
| 收到 SYN-ACK | 收到 SYN | 网络正常,问题在应用层(状态码或超时) |
| 收到 RST | 收到 SYN | 端口没有监听,或本机规则主动拒绝 |
抓包点选错会白忙一场:容器跑在独立网络命名空间时,宿主机物理网卡上可能看不到容器内部流量。优先在容器所在命名空间,或节点对外出口抓,并明确记录抓包位置。
生产环境抓包必须带过滤表达式并限制包数(-c 或配合 -w 加超时),长时间不加过滤地抓大量小包会明显拖慢机器,也可能把磁盘写满。