Linux查丢包必须分层定位:先看/proc/net/dev的Rx-OVR(Ring Buffer溢出)和Rx-DRP(内核丢包),再用ethtool -S盯rx_dropped、rx_over_errors、rx_fifo_errors、rx_missed_errors四字段,最后检查tc规则是否人为丢包。

Linux 没有“一键查丢包原因”的命令,必须按数据流向分层看:先确认是否真丢了,再判断丢在哪一层——网卡硬件、驱动 Ring Buffer、内核协议栈,还是人为 tc 规则。跳过分层直接 grep drop 会漏掉 rx_missed_errors 这类关键字段,也容易把 tx_aborted_errors 当成发送丢包。
怎么看 /proc/net/dev 里的 Rx-OVR 和 Rx-DRP
这是最轻量、最稳定的入口级判断依据,比 ifconfig 或 ip -s link 更可靠:
-
Rx-OVR > 0→ Ring Buffer 溢出,包在网卡 DMA 写入阶段就被丢弃,属于硬件/驱动层瓶颈;立刻执行ethtool -g eth0查当前大小,再试ethtool -G eth0 rx 4096扩容 -
Rx-DRP > 0且Rx-OVR == 0→ 包已进 Ring Buffer,但被内核丢弃,下一步该查netstat -s | grep "packet receive errors"或cat /proc/net/softnet_stat第 2 列(dropped) - 虚拟网卡(如
virtio_net)可能不暴露Rx-OVR,此时Rx-DRP上涨 +dmesg | grep -i "missed"出现提示,基本锁定 vCPU 调度问题
怎么用 ethtool -S 定位具体丢包环节
ethtool -S 输出字段混乱,不能无脑 grep -i drop,真正要盯的只有四个字段:
-
rx_dropped:包进了 Ring Buffer,但因内存紧张、net.core.netdev_max_backlog不足、NAPI 轮询延迟高被内核丢弃 -
rx_over_errors:Ring Buffer 溢出,驱动取包太慢,和Rx-OVR高度相关 -
rx_fifo_errors:物理 FIFO 溢出,多见于小包高吞吐场景,需结合驱动版本和固件状态判断 -
rx_missed_errors:虚拟化环境核心信号,vCPU 调度不及时导致中断丢失,值上升可直接关联宿主机 CPU 负载或 vCPU 绑定不合理
注意:rx_errors 是 CRC/frame/length 等链路层错误总和,只说明物理链路质量差(线缆/光衰),不等于丢包;tx_aborted_errors 是冲突重试失败,也不是发送丢包。
怎么确认 tc 规则在主动丢包
tc 规则造成的丢包完全不会出现在网卡统计里,是生产环境最常被误判的“幽灵丢包”:
- 运行
tc qdisc show dev eth0,重点找含netem、loss、policer、fq_codel的规则 - 加
-s参数看真实丢包数:tc -s qdisc show dev eth0,关注输出中dropped列是否在涨 - 容器环境要查透:CNI 插件(如 Calico、Cilium)可能在 host interface 上挂了 tc 规则,别只查
eth0,也检查cali+或lxc+类虚拟接口
为什么 ifconfig 的 dropped=0 不能说明没丢包
ifconfig 的 dropped 和 overruns 只反映内核软中断处理完之后的丢弃,漏掉了更早环节:
- 网卡 DMA 写入 Ring Buffer 时 buffer 满了 → 包被硬件丢弃,
ifconfig不统计,得靠ethtool -S eth0 | grep -E "(rx_|tx_).*[dD]rop|fifo|miss" - 驱动绕过标准路径(如启用 XDP 或 DPDK)→
overruns可能为 0,但实际丢包仍在发生 -
iptables或nftables在PREROUTING链显式DROP→ 这类丢包不计入ifconfig,得查iptables -t raw -L -v -n或nft list ruleset
真正难缠的丢包,往往发生在 Ring Buffer 和 vCPU 调度之间那几微秒的间隙里——那里没有日志,只有计数器在沉默上涨。


















