mtr是唯一能逐跳定位丢包节点的工具,必须用mtr -n -r -c 50运行,重点看loss%列:某跳高丢包但下一级恢复为0%且目标loss%为0%,属icmp限速假性丢包;若第4跳突增至60%且后续全100%,则问题就在该跳或其上游。

用 mtr 定位丢包发生在哪一跳
单看 ping 只能知道整条链路总丢包率,没法判断是本地网关、运营商骨干网还是目标机房出问题。mtr 是唯一能逐跳统计丢包的工具,关键看 Loss% 列和延迟稳定性。
- 必须加
-n(跳过 DNS 解析,避免卡顿)和-r(报告模式,输出稳定可比):运行mtr -n -r -c 50 14.215.177.39 - 某跳
Loss%高但下一级跳恢复为 0%,且最终目标Loss%是 0%,大概率是该跳主动限速 ICMP,不是真实丢包 - 如果第 4 跳
Loss%突增至 60%,后续所有跳都 100%,说明问题就在第 4 跳设备本身或其上游链路 -
StDev> 50ms 或Wrst远大于Avg,代表网络抖动严重,容易触发 TCP 重传,但不算丢包——别把高延迟当成丢包
查 /proc/net/dev 和 ip -s link 看网卡级丢包分布
/proc/net/dev 和 ip -s link 输出的丢包字段不统一,也不能直接相除算“丢包率”。它们反映的是不同层级的丢弃行为,必须分开看:
-
Rx-DRP(ip -s link中的RX: dropped):包已进 Ring Buffer,但被内核协议栈丢弃,常见于 socket buffer 满、无监听端口、内存不足 -
Rx-OVR(ip -s link中的RX: overruns):Ring Buffer 溢出,DMA 写入时覆盖旧包,属于硬件级丢包,说明驱动取包太慢或 CPU 处理不过来 -
RX: errors:物理层错误,比如rx_crc_errors或rx_frame_errors,指向线缆松动、光衰、双工不匹配 -
TX: dropped:发送侧丢包,常见于 qdisc 队列满(如默认pfifo_fast只有 1000 包),或tc限速规则生效
用 ethtool -S 拆解驱动内部丢包计数器
ethtool -S 显示的是驱动原生统计,比 /proc/net/dev 更细、更准,但不是所有网卡都支持完整字段。重点关注这几个字段:
-
rx_missed_errors:Ring Buffer 满了来不及收,内核没处理就被覆盖,典型原因是中断响应慢或 CPU 过载 -
rx_fifo_errors:DMA FIFO 溢出,多见于高吞吐 UDP 场景,常与rx_missed_errors成对出现 -
rx_dropped:驱动主动丢弃,可能因校验失败、帧长异常,或启用了rp_filter导致反向路径验证失败 -
tx_aborted_errors:发送时载波丢失、冲突超限等,一般对应物理链路问题 - 执行
ethtool -S eth0 | grep -i "drop\|fifo\|miss\|crc",若rx_fifo_errors显著增长,优先调大 Ring Buffer:ethtool -G eth0 rx 4096
确认有没有 tc 在静默丢包
很多“丢包”根本不是故障,而是人为配置的限流策略,完全不体现在网卡统计里。哪怕 /proc/net/dev 和 ethtool -S 全是 0,tc 也可能在偷偷丢包:
- 运行
tc qdisc show dev eth0,看是否有netem、loss、policer等关键字 - 带
-s参数看真实丢包数:tc -s qdisc show dev eth0,关注dropped列数值 - 容器环境要查虚拟接口:
tc qdisc show dev cali0或lxc+类接口,CNI 插件(如 Calico、Cilium)常在 host interface 上挂规则 - 误配的
tc qdisc add dev eth0 root netem loss 5%会让 5% 出向包静默消失,ping和tcpdump -i eth0都能看到请求发出但无响应——此时删规则比调内核参数管用得多:tc qdisc del dev eth0 root
rx_missed_errors 高但 UdpInErrors 低,说明丢包卡在 Ring Buffer 到协议栈之间;而 UdpInErrors 高但 rx_missed_errors 为 0,问题大概率出在 socket buffer 太小或应用读得太慢。这些交叉线索,才是定位丢包分布的关键。











