linux无直接计算丢包率的命令,所有工具如ifconfig、ip -s link、/proc/net/dev仅提供绝对计数器,因分母不统一、层级不同,不可简单相除;须先定位丢包层级:rx-drp(协议栈丢弃)、rx-ovr(ring buffer溢出)、ethtool -s查rx_fifo_errors等驱动级计数器、tc -s qdisc确认人为限流、netstat -s和conntrack -s补全协议栈上层丢包。

ifconfig、ip -s link、/proc/net/dev 里所有字段都是**绝对计数器**,不能简单用 dropped / packets 相除——分母不统一、统计层级不同,结果毫无意义。
真正要定位丢包,得先确认丢包发生在哪一层,再选对应工具看具体计数器。
看 /proc/net/dev 的 Rx-DRP 和 Rx-OVR 列
这是最轻量、兼容性最好的入口,反映接收路径两个关键丢点:
-
Rx-DRP:包已进 Ring Buffer,但被内核协议栈丢弃(如 socket buffer 满、无监听端口、内存不足) -
Rx-OVR:Ring Buffer 溢出,网卡 DMA 写入时直接覆盖旧包——硬件级丢包,ifconfig的overruns就是它
执行 watch -n1 'cat /proc/net/dev | grep eth0',观察这两列是否持续上涨。若 Rx-OVR 非零且增速快,说明驱动取包太慢,优先调大 Ring Buffer:ethtool -G eth0 rx 4096。
用 ethtool -S 查驱动原生丢包计数器
/proc/net/dev 是通用接口,而 ethtool -S eth0 输出的是驱动芯片级寄存器值,字段更细、定位更准:
- 查溢出类:
rx_fifo_errors(物理 FIFO 满)、rx_missed_errors(vCPU 调度不过来,虚拟化环境关键指标) - 查链路异常:
rx_crc_errors、rx_frame_errors(线缆/光模块/双工不匹配) - 别用
grep -i drop——会漏掉rx_missed_errors等关键字段,也可能把tx_aborted_errors(重试失败)误当丢包
运行 ethtool -S eth0 | grep -E "(rx_|tx_).*[dD]rop|fifo|miss|crc)"。注意:部分老 virtio 驱动不支持 ethtool -S,输出 no stats available 是正常现象,不是没丢包。
确认有没有 tc 在主动丢包
很多“丢包”根本不是故障,而是人为配置的限流策略,且完全不体现在网卡统计里:
- 运行
tc qdisc show dev eth0,看是否有netem、loss、policer等关键字 - 加
-s参数看真实丢包数:tc -s qdisc show dev eth0,重点关注dropped列是否在涨 - 容器环境要特别小心:CNI 插件(如 Calico、Cilium)可能在 host interface 上挂了 tc 规则,别只查
eth0,也检查cali+或lxc+类虚拟接口
例如 tc qdisc add dev eth0 root netem loss 5% 会让 5% 出向包静默消失,ping 和 tcpdump -i eth0 都能看到请求发出但无响应——此时删规则比调内核参数管用得多:tc qdisc del dev eth0 root。
别跳过 netstat -s 和 conntrack -S
网卡和驱动层清白,不代表没丢包。协议栈上层丢包必须靠这些补全:
-
netstat -s | grep -A 5 "Udp:":看packets to unknown port received(端口无监听)、packet receive errors(socket buffer 满) -
netstat -s | grep -A 5 "Tcp:":关注failed connection attempts、connections reset是否异常升高 -
conntrack -S:查连接跟踪表溢出(insert_failed> 0 表示 conntrack 表满,新连接被丢)
这些丢包不会出现在 /proc/net/dev 或 ethtool -S 里,但对业务影响一样严重。尤其在高并发短连接场景下,conntrack -S 的 insert_failed 常被忽略。











