引言
学习如何使用 traceroute 和 MTR 诊断网络问题是一个实用的步骤,当你需要查看你的机器与远程主机之间的路由器、某跳是否存在延迟峰值,以及丢包是否真实还是探测处理方式的伪象时。Traceroute 提供前向路径的单一快照。MTR 将 traceroute 式的发现与重复探测相结合,从而可以为每跳构建丢包和往返时间统计。
本教程将介绍基于 TTL 的追踪工作原理、在常见操作系统上安装和运行 traceroute 和 mtr 的方法、如何阅读带注释的输出、当双向路径不同时的情况,以及在将日志附加到支持票据之前可以使用的简短故障排查流程。有关接口和协议的背景知识,请参阅 An Introduction to Networking Terminology, Interfaces, and Protocols。
关键要点
- Traceroute 通过发送 TTL 值递增的数据包并记录每跳的 ICMP “time exceeded” 回复来发现前向路径;MTR 重复这一思路并添加实时统计(丢包、最小值、平均值、最大值、标准差)。
traceroute输出中的星号通常表示路由器未响应探测,并不一定意味着用户流量被丢弃。始终与指向最终跳的 MTR 以及应用层症状进行比较。- 路径可能是不对称的:从你的笔记本电脑运行
mtr到服务器,并从服务器回向你的公网 IP(或另一个稳定的端点)运行,当双方均可达时。 - RTT 粗略指南用于解释:同一都市圈通常每跳低于约
5 ms;大国家跨国段通常为数十毫秒;跨洋段通常约为80 ms到150 ms。某跳持续高于约150 ms到200 ms的值值得在上下文中仔细检查。 - 当路由工具不足时,使用
tcpdump或 Wireshark 等工具捕获数据包,使用ss检查套接字,并审查本地防火墙规则。在 Ubuntu 上,请参阅 How To Set Up a Firewall with UFW。
先决条件
- Linux 或 macOS shell,或带有
tracert的 Windows(以及可选的第三方 MTR 构建),用于平台特定部分。 - 到测试主机的网络出口。如果你正在测试 Droplet,可以 SSH 登录并在实例上运行命令。如果需要复习,请遵循 How to Connect to Your Droplet with SSH。
- 如果你的 OS 需要提升权限来使用某些探测类型(如 ICMP 或 raw sockets),则需要
sudo或管理员权限。
什么是网络跳数
跳数 是路径上的一台路由器或 layer-3 设备。从家庭或办公网络到云实例,你的 data包 会跨越许多跳数。
你的 PC -- 跳 1 (边缘路由器) -- 跳 2 (ISP) -- 跳 3 (骨干网) -- ... -- 目标
每个跳数会递减 IP TTL。当 TTL 达到零时,该设备应返回 ICMP time exceeded 消息,这就是经典 traceroute 用于发现该跳数的机制。
traceroute 的功能及其工作原理
Traceroute 回答的问题是:“我的数据包在前往此目的地的途中经过了哪些路由器,以及我观察到的每个路由器的往返时间是多少?”在许多 Linux 系统上,默认的来自 iputils 的 traceroute 会向高位端口发送 UDP 探测包,并监听 ICMP 响应。在 macOS 上,系统的 traceroute 也默认使用 UDP。当你希望行为更接近 ping 时,可以在 Linux 上(支持的情况下)使用如 -I 等标志请求 ICMP echo 探测。
基于 TTL 的探测
发送方从较小的 TTL 开始。第一跳路由器丢弃数据包,返回“时间超过”消息,并揭示其身份。发送方逐步增加 TTL,直到数据包到达目的地(或达到跳数限制)。
ICMP、UDP 和 TCP 风格的跟踪
- ICMP:类似于
ping;某些网络会将 ICMP 与 TCP 或 UDP 应用流量区别对待。 - UDP:许多
traceroute实现的常见默认选项。 - TCP:当 ICMP 或 UDP 被过滤但 TCP 端口开放时,可以使用如
tcptraceroute或mtr -T等工具。
traceroute 的局限性
- 防火墙和速率限制:运营商可能过滤或对 ICMP 或奇数 UDP 端口进行速率限制,即使 HTTP 或 SSH 正常工作,输出中也会显示
*。 - 非对称路由:ICMP 消息的返回路径可能与你的应用流量所走的路径不同。
- 负载均衡器和 anycast:如果目的地使用 anycast 或负载均衡,在多次运行之间你可能会看到不同的跳数。
有关解释跟踪的更深入阅读,请参阅 APNIC 文章 如何正确解释 traceroute 或 MTR。
安装 traceroute 和 MTR
Ubuntu 和 Debian
大多数 Ubuntu 镜像已包含 traceroute。如果缺失:
- sudo apt update
- sudo apt install traceroute
安装 MTR(CLI;包含 mtr 和可选的 TUI)。如果你想要更小的仅 CLI 包,可以使用 mtr-tiny:
- sudo apt install mtr
Rocky Linux、CentOS Stream、Fedora 和 RHEL 系列
在当前版本中使用 dnf(较旧系统可能仍使用 yum):
- sudo dnf install traceroute mtr
macOS
traceroute 已预装。使用 Homebrew 安装 MTR:
- brew install mtr
Homebrew 可能将 mtr 安装为 mtr 或提示路径;安装后运行 mtr --version 以确认。
Windows
tracert 已内置。打开命令提示符或 PowerShell:
- tracert example.com
pathping 结合路由跟踪和持续丢包采样:
- pathping example.com
Windows 未捆绑原生 MTR;许多管理员如果需要在 Windows 客户端上使用 MTR 语义,会选择维护的第三方构建版本。
运行 traceroute 并解读输出
基本语法
- traceroute example.com
将 example.com 替换为允许测试的主机名或 IP。
示例输出(带注释)
你的地址和主机名会有所不同。此示例显示了常见的字段:
traceroute to example.com (93.184.216.34), 30 hops max, 60 byte packets
1 gateway.lan (192.0.2.1) 2.1 ms 2.0 ms 2.2 ms # 你的边缘路由器
2 isp-core.example.net 10.4 ms 10.1 ms 10.3 ms # 提供商回程链路
3 * * * # 本轮无回复
4 core.backbone.example 18.2 ms 17.9 ms 18.0 ms # 仍在推进
...
解读每列
- 跳数:从你的主机开始的步数距离。
- 主机名或 IP:来自反向 DNS,如果缺少 PTR 则为数字地址。
- 三个往返时间:默认发送三个探测;它们可能因拥塞或多路径而变化。
常用标志
增加最大跳数(默认为 30;许多构建的最大值为 255):
- traceroute -m 64 example.com
更改每跳的探测次数:
- traceroute -q 1 example.com
跳过反向 DNS 以运行得更快:
- traceroute -n example.com
在许多 Linux 系统上,你可以在主机后添加长度参数来更改数据包大小(负载长度):
- traceroute example.com 70
星号的含义
星号表示该探测在超时前未收到有效回复。这通常表明中间路由器不响应 traceroute 探测、ICMP 速率限制,或防火墙策略。如果后续跳数仍能显示,用户流量可能仍能正常工作。将 * 视为信号,与 MTR、应用测试以及可能的抓包进行验证。
识别问题跳数
寻找第一个延迟与前一个稳定跳数相比急剧增加的跳数,或者出现丢包并且最后一个跳数也显示丢包或应用失败的跳数。如果只有中间跳数显示丢包但 MTR 中目标干净,则中间丢包可能是控制平面降权而非转发路径损坏。
MTR 的功能及其与 traceroute 的区别
MTR(Matt’s traceroute,通常打包为 mtr)发送重复探测并更新每跳的统计信息。这使其比一次性 traceroute 更适合检测间歇性丢包和抖动。
| 功能 | Traceroute | MTR |
|---|---|---|
| 跳数的单次快照 | 是 | 可选报告模式 |
| 持续更新 | 否 | 是(默认 TUI) |
| 每跳丢包百分比 | 否 | 是 |
| 延迟的标准差 | 否 | 是 |
| TCP 跟踪模式(取决于构建) | 罕见 | 通常可用(-T) |
MTR 列含义
在报告模式下,你通常会看到:
- Loss%:采样窗口内该跳丢失回复的百分比。
- Snt:发送的数据包数。
- Last, Avg, Best, Wrst:以毫秒为单位的往返时间。
- StDev:延迟样本的离散度(有用的抖动信号)。
何时优先使用 MTR
当问题为间歇性时、当你需要向提供商提供证据时,或当你想查看“坏”的中间跳数是否仍通向健康的最终跳数时,使用 MTR。
运行 MTR 并解读报告
交互模式
- mtr example.com
TUI 会持续刷新,直到你退出(通常按 q)。
非交互报告
默认发送 10 个周期(确切标志取决于版本;--report 广泛可用):
- mtr --report example.com
增加周期以获得更稳定的采样:
- mtr --report --report-cycles 50 example.com
示例报告(数值仅供说明):
HOST: myserver Loss% Snt Last Avg Best Wrst StDev
1.|-- gateway.lan 0.0% 50 0.4 0.5 0.3 1.1 0.2
2.|-- isp-pe.example.net 0.0% 50 9.2 10.1 8.4 15.2 1.8
3.|-- core1.backbone.example 0.0% 50 18.0 18.4 17.1 22.0 1.1
4.|-- core2.backbone.example 0.0% 50 88.5 90.2 85.1 120.4 10.3
5.|-- target.example.com 0.0% 50 91.0 92.0 89.0 125.0 11.0
在这种模式下,延迟在第 4 跳急剧上升,并保持较高水平直至目的地,这指向路径的该段(受下面不对称因素的影响)。
中间跳跃的丢包与目的地的丢包
如果中间跳跃显示丢包,但最终跳跃显示约 0% 丢包且服务正常工作,则中间丢包可能是因为该路由器对探测流量进行了降权或限制。如果最终跳跃显示持续丢包且与应用错误匹配,则将其视为端到端丢包。
私有地址和 MPLS
你可能会看到提供商骨干网上的 RFC 1918 地址或简短标签。这在 MPLS 或运营商网络中很常见。重点关注延迟或丢包相对于相邻跳跃的变化,而不是标签是否“漂亮”。
诊断常见问题
单跳高延迟
单跳处的急剧跳跃表明拥塞、较长的地理段或可疑的对等点。使用 MTR 跨时间比较,并从另一个网络(例如手机热点与办公室 Wi-Fi)测试,以查看跳跃是否稳定。
丢包模式
- 端到端丢包 在最后一跳出现且与用户可见故障匹配,通常需要使用 MTR 报告和时间戳进行升级处理。
- 仅中间跳跃丢包 且最后一跳干净,通常需要解释,而不是紧急路由更改。
完全超时
如果跟踪完全停止,检查本地出口、VPN、企业代理、安全组或云防火墙。在 Linux 主机上,还需确认本地 iptables 或 nftables 规则未阻止探测。对于开放监听器和超出路由的连接性检查,你可以使用
How To Use Netcat to Establish and Test TCP and UDP Connections
和
How To Use Nmap to Scan for Open Ports on Your VPS。
双向测试
A 到 B 和 B 到 A 的路径可能不同。正向跟踪看起来干净,但某些流量的返回路径可能较差。
当两端都有 shell 访问权限时(例如你的笔记本电脑和 Droplet):
- 从客户端运行
mtr --report <target>到服务器公网 IP 或主机名。 - 从服务器运行
mtr --report到客户端的公网 IP。
如果客户端位于运营商级 NAT 后面且没有稳定的入站 IP,则使用双方均可访问的已知反射器,或从你控制的带有公网地址的小型云 VM 的一条路径腿进行测试。
并排比较两个报告,并注意延迟或丢包发散的位置。
实际故障排查工作流程
当用户报告“服务器感觉很慢”或“SSH 连接中断”时,使用此序列。
- 确认 DNS 和 L4 可达性:解析名称,当策略允许时,使用
ping或连接到服务端口。 - Traceroute 快照:
traceroute -n <host>获取快速路径图。 - MTR 报告:
mtr --report --report-cycles 50 <host>(调整循环次数)。 - 方向性:从远程主机向客户端或稳定的公共端点反向重复执行。
- 本地策略:验证 UFW 或云防火墙未阻止所需流量。有关端口概念,请阅读 在 Linux 上打开端口。
- 升级捆绑包:附上带时间戳的 MTR 报告、源和目标 IP,以及问题是否与特定 ISP 或 VPN 相关。
当 traceroute 和 MTR 不足以解决问题时
- 数据包捕获:在接口上使用
tcpdump,或在笔记本上使用 Wireshark,以查看重传、复位和 DNS 异常。 - Socket 状态:
ss -tunap(netstat的现代替代品),查看监听和连接状态。 - Kubernetes:对于运行在 Kubernetes 上的工作负载,还需审查服务路由和 CNI 行为,使用 如何检查 Kubernetes 网络。
- 高级内核内省:基于 eBPF 的工具(例如使用正确探针的
bpftrace)在复杂生产环境中很有帮助,但需要单独的专业知识和安全的部署实践。
向提供商提交 MTR 报告
纯文本易于粘贴到工单中:
- mtr --report --report-cycles 100 example.com > mtr-client-to-server.txt
尽可能运行匹配的反向测试,并用方向、时区和源 IP 标记文件。
历史说明
经典的 traceroute 理念与 Van Jacobson 在 1980 年代后期对 Unix 网络工具的工作相关。MTR 后来出现,将重复测量与路径发现合并,这符合网络运营商实际隔离不稳定路径的方式。这两个工具仍是 Linux 和 BSD 服务器(包括您自己管理的云主机)上的日常实用工具。
常见问题解答
1. 如何使用 traceroute 识别网络问题?
运行 traceroute <destination>(Windows 上为 tracert),查找与早期跳相比延迟突然增加的第一个跳,或星号聚集且您的应用也失败的位置。将此与 mtr --report 结合使用,以避免被单一幸运快照误导。
2. 如何使用这些工具诊断网络连接问题?
从基本可达性开始(ping 或当 ICMP 被阻止时的 TCP 连接测试)。然后向服务 IP 运行 mtr --report。如果服务是双向的,从两端或每侧向稳定的公共端点运行 MTR,以考虑非对称路由。
3. 如何使用 MTR 进行故障排查?
事件期间使用交互模式进行实时监控。对于工单,使用足够的循环次数的报告模式,例如 mtr --report --report-cycles 50 <host>。如果 UDP 或 ICMP 被过滤,当您的构建支持时,使用 -T 向开放端口探索 TCP 模式。
4. MTR 和 traceroute 一样吗?
不。Traceroute 每次运行发现一次跳(除非您脚本化重复)。MTR 反复探测并汇总每个跳的丢包和往返统计,更接近间歇性问题所需的内容。
5. traceroute 输出中的星号是什么意思?
它们表示探针在超时前未收到回复。常见原因包括 ICMP 过滤、速率限制,或不优先处理 traceroute 流量的路由器。如果跟踪继续通过星号且 MTR 显示最终跳健康,则路径对实际应用流量可能仍正常。
结论
您可以使用 traceroute 和 MTR 来诊断网络问题,方法是通过映射跳跃、比较往返时间,以及读取最终跳跃与中间跳跃的丢包情况。当存在不对称性时,添加双向测试;如果路由看起来正常但应用程序仍失败,则转向数据包捕获和 socket 检查。
后续步骤和相关资源
- 网络术语、接口和协议简介
- 如何在 Ubuntu 上使用 UFW 设置防火墙
- 如何检查 Kubernetes 网络
启动一个 Linux 虚拟机
启动一个 Droplet,并在您的家庭连接和实例之间练习正向和反向 mtr。