Linux丢包需分层定位:先查/proc/net/dev的Rx-DRP(内核协议栈丢弃)和Rx-OVR(Ring Buffer硬件溢出),再用ethtool -S看rx_dropped、rx_missed_errors等驱动级指标,同时排查tc/qdisc人为丢包、软中断压力、conntrack耗尽及防火墙规则。

Linux 没有“丢包详情”这种一键汇总的视图,所有所谓“详情”都是分层散落在不同位置的计数器——你得知道去哪查、查什么字段、为什么这个值上涨才算真问题。
看 /proc/net/dev 里的 Rx-DRP 和 Rx-OVR
这是最轻量、最稳定的第一入口,不用装额外工具,兼容所有内核版本:
-
Rx-DRP:包已进 Ring Buffer,但被内核协议栈丢弃(如 socket 缓冲区满、无监听端口、内存分配失败) -
Rx-OVR:Ring Buffer 溢出,新包直接被网卡硬件覆盖——这是硬性丢包,说明驱动取包太慢或中断响应不及时 - 执行
watch -n1 'cat /proc/net/dev | grep eth0',盯着这两列是否持续上涨;若Rx-OVR非零且增长快,优先调大 Ring Buffer:ethtool -G eth0 rx 4096 - 注意:
ifconfig显示的overruns就是Rx-OVR,但它不显示Rx-DRP,所以别用ifconfig查丢包原因
用 ethtool -S 查驱动级丢包字段
/proc/net/dev 是通用接口,ethtool -S 才是驱动原生计数器,字段更细、定位更准:
- 重点盯:
rx_dropped(驱动层主动丢)、rx_missed_errors(vCPU 调度不及时,虚拟化环境关键指标)、rx_fifo_errors(DMA FIFO 溢出)、rx_crc_errors(物理链路问题,如光衰、线缆松动) - 运行
ethtool -S eth0 | grep -E "(drop|miss|fifo|crc)",比对rx_fifo_errors和/proc/net/dev中的Rx-OVR是否一致;若前者远大于后者,说明驱动绕过了标准路径(如启用了 XDP),/proc/net/dev统计已失效 - 部分虚拟网卡(如老版 virtio)或 USB 网卡可能不支持
ethtool -S,输出No data available是正常现象,不代表没丢包
确认有没有 tc 在静默丢包
这是生产环境最常被忽略的“幽灵丢包”——网卡统计清白,但流量就是少了一截:
- 运行
tc qdisc show dev eth0,看是否有netem、loss、policer字样 - 加
-s参数看真实丢包数:tc -s qdisc show dev eth0,关注输出中dropped列是否在涨 - 容器环境要查全:CNI 插件(如 Calico 的
cali+、Cilium 的lxc+)可能在虚拟接口上挂了规则,不能只查eth0 - 误配的
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 -A5 -B5 "packet.*error"查UdpInErrors(socket buffer 满)、TcpExtListenOverflows(全连接队列溢出)等 -
conntrack -S看连接跟踪表丢包,如insert_failed(哈希冲突/表满)、drop(被 nf_conntrack 模块丢弃) - 若
Rx-DRP高但UdpInErrors低,说明丢包卡在 Ring Buffer 到协议栈之间,要调net.core.netdev_max_backlog或关 IRQ balance -
ss -i可查具体 socket 的rcv_space和rcv_ssthresh,确认是否应用读取太慢导致缓冲区持续满
真正麻烦的不是找不到计数器,而是多个层级同时丢包时,哪个是根因、哪个是结果。比如 rx_missed_errors 上涨引发 Rx-DRP 跟着涨,但你只盯着 Rx-DRP 调 net.core.rmem_max 就会无效——得先压住 vCPU 调度延迟。


















