必须加 -r -c 20 -n -4 参数组合才能可靠诊断链路问题:-r 输出统计结果而非交互界面,-c 20 每跳发20包避免偶然性,-n 跳过dns解析防卡顿,-4 强制ipv4避双栈干扰。

直接用 mtr 能看到链路中哪一跳开始丢包或延迟突增,比 ping 和 traceroute 单次探测更可靠;但默认交互式运行、不加参数容易误判,尤其在目标屏蔽 ICMP 或存在多出口时。
为什么不能直接跑 mtr www.example.com 就完事
默认交互模式下,mtr 会持续发包、实时刷新界面,无法保存结果,也不适合脚本调用。更关键的是:它默认做反向 DNS 解析,遇到中间节点不响应 PTR 记录时会卡顿数秒,导致首几跳显示为 ??? 或延迟虚高;同时没限定发包次数,你可能只看了前 5 秒就关掉,而问题节点恰好在第 12 跳才暴露。
- 必须加
-r(report 模式)或--report才能一次性输出统计结果 - 搭配
-c指定发包总数,比如-c 20表示每跳发 20 个包,避免偶然抖动干扰判断 - 强烈建议加
-n(no-dns),跳过域名解析,让结果更快更稳 - 若目标明确走 IPv4,显式加
-4,避免双栈环境下因 IPv6 路由异常导致误报
mtr -r -c 20 -n -4 这组参数组合的实际效果
这是生产环境排查最常用的组合,对应一次干净、可复现、可归档的链路诊断:
-
-r:退出后直接打印汇总表格,不进入交互界面 -
-c 20:每跳发送 20 个探测包,足够覆盖常见波动,又不会拖太久(通常 20 秒内完成) -
-n:所有节点只显示 IP,不查 PTR,避免卡顿和解析失败干扰 -
-4:强制走 IPv4,绕过本地 IPv6 配置错误或运营商 IPv6 路由缺失的问题
执行示例:sudo mtr -r -c 20 -n -4 example.com。注意:普通用户需 sudo,因为原始 ICMP 探测需要 cap_net_raw 权限。
遇到丢包集中在某跳,但不是目标服务器时怎么定位
看 Loss% 列:如果从第 5 跳开始持续 100% 丢包,而第 4 跳仍为 0%,说明问题不在你本地网络,极大概率是第 5 跳设备(通常是上层运营商路由器)策略性丢弃 ICMP —— 这很常见,不代表真实业务不通。
- 先确认目标端口是否可达:
telnet example.com 443或curl -I https://example.com,验证 TCP 层是否正常 - 若 TCP 可通但
mtr显示丢包,基本可判定是中间节点禁 ICMP,无需深究该跳 - 若丢包出现在最后 1–2 跳(即目标服务器自身或其直连网关),且
curl也超时,则问题大概率在目标侧:检查其防火墙、安全组、负载均衡健康检查配置 - 不要只看
Loss%,同步观察StDev(标准差):值 > 50ms 说明该跳延迟极不稳定,即使丢包率低,也可能导致重传和业务卡顿
当目标服务器屏蔽 ICMP,mtr 全程无响应怎么办
部分云厂商或企业防火墙默认 DROP 所有 ICMP,此时 mtr 会显示全跳 ??? 或 ??? + 高延迟,实际链路可能是通的。这时要换探测方式:
- 用
--tcp参数改发 TCP SYN 包(需 root):sudo mtr --tcp -P 443 -r -c 20 -n example.com,模拟 HTTPS 端口探测 -
-P 443指定目标端口,避免被中间设备无差别拦截 - 注意:
--tcp在较老版本 mtr(如 CentOS 7 自带)中不可用,需升级到 mtr 0.93+;Ubuntu 22.04+/Debian 12+ 默认支持 - 若连 TCP 模式也无效,说明目标端口被封或路由完全中断,应转向检查 DNS 解析、本地路由表(
ip route get example.com)、以及是否被本地 iptables/nftables 拦截
真正难搞的不是丢包本身,而是丢包发生在“看起来正常”的节点上——比如某跳 Loss% 是 2%,但 StDev 高达 200ms,这种抖动型问题在交互式界面里一闪而过,只有加 -c 固定轮次 + -r 输出才能抓住。










