抓包丢包≠网络丢包,需区分tcpdump自身丢包(如内核缓冲区满、cpu忙)、抓包位置错误、硬件卸载干扰及系统各层真实丢包点。

抓包过程中看到丢包率高,不等于网络真在丢包——更可能是你抓的位置不对、工具配置有误,或者系统根本没把包送到你期望的地方。关键要分清:是“网络丢包”,还是“抓包丢包”。
先确认 tcpdump 本身有没有丢包
tcpdump 依赖内核的 packet capture 机制(如 AF_PACKET),当网卡流量大、CPU 忙或缓冲区小,它会主动丢弃来不及处理的数据包,并在退出时提示 dropped: X packets。这不是网络问题,是抓包能力瓶颈。
- 运行 tcpdump -i eth0 -w /tmp/out.pcap -B 4096 port 80,其中
-B 4096把内核捕获缓冲区设为 4MB(默认通常只有 2MB),能显著减少自身丢包 - 抓完后看输出末尾:
xx packets captured, xx packets received by filter, xx packets dropped by kernel。如果最后一项数字明显增长,说明是 tcpdump 没跟上,不是网络丢包 - 避免用
-n以外的解析选项(如-v、-X),它们加重 CPU 负担;高流量场景优先写入文件再分析
检查抓包位置是否覆盖了真实路径
同一台机器上,不同接口抓到的内容天差地别。抓错地方,会误判丢包发生在某段,其实包根本没走那里。
- 抓 eth0:看到 SYN 但没回包 → 问题可能在本机协议栈、防火墙或应用层(比如 socket 接收队列满)
- 抓 lo:能抓到请求,但 eth0 没发出响应 → 应用已处理,但被 iptables DROP、路由错误或 conntrack 表满拦截
- 抓 any:可同时看到进出方向,适合定位方向性丢包(如只出不进),但性能开销大,慎用于高流量
- 注意:容器内抓包往往看不到宿主机层面的 tc/qdisc 或 iptables 丢包,必须在 host 的物理网卡抓
排除干扰因素:offload 和虚拟化影响
现代网卡常启用硬件卸载(如 GSO、TSO、LRO),导致 tcpdump 看到的不是真实线缆上的帧,而是内核组装/拆分后的逻辑包,容易误读丢包点。
- 临时关闭卸载:ethtool -K eth0 gso off tso off lro off gro off,再抓包对比。若丢包现象消失,说明原先是卸载行为干扰了判断
- 虚拟机或云环境里,rx_missed_errors 上升往往代表 vCPU 调度不过来,不是链路问题;此时即使 tcpdump 显示丢包,根源是资源争抢
- 使用 tcpdump -i eth0 -e 查看以太网帧头,确认 MAC 地址和 VLAN 是否符合预期,排除二层转发异常
验证是否真丢包:交叉比对系统统计
不要只信 tcpdump。把它的结果和内核原始计数器对照,才能锁定丢包环节。
- 查网卡驱动级丢包:ethtool -S eth0 | grep -i "drop\|over\|miss",重点关注
rx_dropped(NAPI 处理慢)、rx_over_errors(Ring Buffer 溢出)、rx_missed_errors(vCPU 过载) - 查协议栈丢包:netstat -s | grep -A5 -B5 "packet receive errors\|overflow\|full",特别关注 UDP 的
receive buffer errors或 TCP 的times the listen queue of a socket overflowed - 查 tc/qdisc 主动丢包:tc -s qdisc show dev eth0,出现
loss XX%或dropped N就是人为限流,和抓包无关











