首页/网络/网络排障速查/抓包缓冲区与内核丢包(-B / dropped by kernel)

抓包缓冲区与内核丢包(-B / dropped by kernel)

高流量下抓包自身会丢包:tcpdump 退出时打印 packets dropped by kernel,说明缓冲或处理能力不足;调大 -B、精简过滤、只抓必需字段是标准解法。

网络排障速查网络更新于 2026-10-13

抓包自己也会丢包

在高流量接口上抓包,丢包的往往不是网络,而是抓包程序:内核把报文放到抓包缓冲区,如果用户态处理不及时,缓冲区满后就地丢弃。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 计数内核接口统计层丢包与抓包丢包分开判定,避免混淆
把抓包丢包当成网络丢包是经典误判:前者只说明抓包能力不足,两者要用不同的证据分别确认。

易错点

  • 看到 dropped by kernel 就下网络丢包的结论:方向完全错误,会误导整条排查路线
  • 默认缓冲在万兆口长时间全量抓包:抓到的样本严重失真,基于它的分析全部不可靠
  • 不落盘直接在终端打印:格式化开销大、更易丢包,应配合 -w 写文件再离线分析
  • 只看 captured 计数不看 dropped:误以为抓取完整,把不完整的样本当成事实依据

数据来源与参考

  • man 8 tcpdump(-B 与丢包统计说明)
  • man 8 ip-link(-s 统计)

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌