抓包自己也会丢包
在高流量接口上抓包,丢包的往往不是网络,而是抓包程序:内核把报文放到抓包缓冲区,如果用户态处理不及时,缓冲区满后就地丢弃。tcpdump 退出时会打印「packets dropped by kernel」,这个数字只要非 0,就说明抓到的样本不完整。判读结论前必须先确认这一点,否则会把自己的采样偏差当成网络故障。
基本信息
| 适用平台 | Linux(tcpdump/libpcap,内核抓包缓冲以块为单位) |
|---|---|
| 关键输出 | 退出时的 packets captured 与 packets dropped by kernel |
| 缓解参数 | -B 指定缓冲区大小(单位 KiB,如 -B 32768 约 32MB)、-s 减小 snaplen、-q 减少格式化开销 |
| 过滤优化 | 条件尽量靠前且精确,减少进入用户态的报文量 |
| 对照手段 | ip -s link 与 nstat 判断内核统计层是否也有丢包 |
典型使用场景
- 万兆接口长时间抓包:先加大缓冲并精简过滤,保证样本可用
- 确认抓包结果可信度:每次抓取后都检查 dropped 计数
- 给厂商提供抓包证据前:确认样本完整,否则结论可能被推翻
- 排查偶发故障:长时间低流量抓取时用 -B 提高缓冲更稳
- 区分抓包丢包与网络丢包:两者必须分别取证
丢包确认与缓解
丢包确认与缓解
sudo tcpdump -nn -i eth0 -B 32768 -w /tmp/big.pcap 'host 10.0.0.5' # 32MB 缓冲并落盘
# 退出时会打印统计:
# 12345 packets captured
# 67 packets dropped by kernel
# 缩小 snaplen 只抓头部,显著降低处理压力
sudo tcpdump -nn -i eth0 -q -s 128 -c 100000 'tcp port 443'
# 内核统计层的对照口径
ip -s link show eth0 | grep -A2 RX
nstat -az | grep -iE 'UdpInErrors|TcpExtTCPBacklogDrop'判据与处置
| 指标/配置 | 含义 | 处置 |
|---|---|---|
| packets dropped by kernel | 抓包缓冲溢出丢弃 | 非 0 即样本不完整,先加大 -B |
| -B 缓冲大小 | 内核抓包缓冲容量 | 高流量接口至少 32MB,视速率提高 |
| -s snaplen | 每包截取的字节数 | 只关心头部时用 128 或 96 降低开销 |
| 过滤条件 | 决定进入用户态的报文量 | 条件写精确并尽量靠前 |
| ip -s link 计数 | 内核接口统计层丢包 | 与抓包丢包分开判定,避免混淆 |
把抓包丢包当成网络丢包是经典误判:前者只说明抓包能力不足,两者要用不同的证据分别确认。