
1. 网络排障绕不开的那条路径做运维或者后端开发的朋友大概率都遇到过这种场景服务部署在远端本地访问时通时不通ping 能通但业务请求就是超时或者跨机房调用延迟忽高忽低。这时候光靠ping已经不够用了因为ping只告诉你“对方在不在”却不告诉你“数据包到底走了哪条路、在哪一跳开始变慢或丢包”。traceroute就是干这个的——它把数据包从本机到目标主机之间经过的每一跳路由器都列出来让你一眼看清路径上的瓶颈和断点。这篇文章面向的是刚接触 Linux 网络排障的开发者、运维新人以及需要经常定位跨网络链路问题的后端同学。我会从 traceroute 的工作原理讲起把安装、常用参数、输出解读、典型故障排查、和 mtr 的配合使用全部串一遍。内容基于我这些年实际排障的经验不是照搬手册很多参数组合和坑点都是踩出来的。读完你至少能做到拿到一台陌生 Linux 机器能快速装上 traceroute看懂它的输出并且用它对常见的“网络不通/慢/丢包”问题做出初步判断。需要先说明一点traceroute 依赖 ICMP 和 UDP/TCP 探测包很多云厂商的安全组、防火墙会拦截这些探测包导致输出里出现大量* * *。这不代表链路真的断了而是探测包被中间设备丢弃了。理解这一点是读懂 traceroute 输出的前提后面我会专门展开讲。2. traceroute 到底在干什么原理拆解2.1 TTL 递减机制是核心要理解 traceroute先得理解 IP 协议里的TTLTime To Live生存时间字段。每个 IP 数据包头部都有一个 TTL 值初始通常是 64 或 128。数据包每经过一个路由器TTL 就减 1。当 TTL 减到 0 时路由器会丢弃这个包并回送一个ICMP Time Exceeded超时消息给源地址。traceroute 就是利用这个机制工作的。它先发一个 TTL1 的探测包第一个路由器收到后 TTL 减为 0于是回一个 ICMP 超时消息traceroute 就记录下第一个路由器的地址。接着发 TTL2 的包第二个路由器回消息记录第二跳。如此递增直到探测包到达目标主机或者达到最大跳数限制默认 30 跳。这个设计非常巧妙——它不需要目标主机配合路径上的任何一台路由器都会“主动汇报”自己的存在。你可以把它想象成寄快递时每经过一个中转站就盖一个章最后你拿到包裹上的章就知道它走了哪些中转站。2.2 三种探测方式的选择traceroute 默认使用UDP 探测包目标端口从一个较大的端口号默认 33434开始递增。为什么用 UDP 而不是 ICMP因为早期很多系统对 ICMP Echo 请求的处理优先级很低甚至直接不响应而 UDP 到高位端口的包通常会被目标主机正常处理并返回 ICMP Port Unreachable端口不可达traceroute 收到这个就认为到达终点了。不过现在网络环境复杂了UDP 探测经常被防火墙拦截。所以 traceroute 也支持另外两种方式ICMP 模式-I发送 ICMP Echo 请求类似 ping。优点是很多网络对 ICMP 放行较宽松缺点是部分设备会限速 ICMP。TCP 模式-T发送 TCP SYN 包到指定端口常用 80 或 443。这是穿透防火墙能力最强的方式因为 80/443 端口通常必须开放。缺点是目标端口如果没开服务可能收不到响应。选择哪种方式取决于你的网络环境。我的经验是先试默认 UDP不通就换 TCP 到 443再不行试 ICMP。这个顺序能覆盖绝大多数场景。2.3 每跳发几个包traceroute 默认对每一跳发送3 个探测包所以你会看到每行有 3 个时间值。这三个值代表三次探测的往返延迟RTT。如果某个包没收到响应就显示*。三个值差异大说明链路抖动三个都是*说明这一跳的探测包被丢弃或超时了。这里有个细节三个时间值不一定来自同一台路由器。如果路径存在负载均衡ECMP不同探测包可能走不同路径导致同一跳显示多个 IP 地址。这是正常现象不是故障。3. 安装不同发行版的正确姿势3.1 主流发行版安装命令traceroute 在大多数 Linux 发行版里不是默认安装的需要手动装。下面是我整理的常见发行版安装方式发行版包管理器安装命令Debian/Ubuntuaptsudo apt update sudo apt install tracerouteCentOS/RHEL 7yumsudo yum install tracerouteCentOS/RHEL 8/Rocky/Almadnfsudo dnf install tracerouteFedoradnfsudo dnf install tracerouteArch/Manjaropacmansudo pacman -S tracerouteopenSUSEzyppersudo zypper install tracerouteAlpineapksudo apk add traceroute装完之后用traceroute --version验证一下。如果提示命令找不到检查一下/usr/sbin是否在 PATH 里——有些发行版把 traceroute 装在 sbin 目录下普通用户默认 PATH 可能不包含它。3.2 最小化系统里的依赖问题在容器或最小化安装的系统里可能会遇到依赖缺失。Debian 系一般会自动处理依赖但如果你手动下载 deb 包安装可能缺libc6之类的基础库。CentOS 最小化安装时traceroute依赖glibc和libm通常系统自带。还有一种情况某些精简镜像里连iputils都没有ping都用不了。这时候建议先装iputils-pingDebian或iputilsRHEL再装 traceroute。因为排障时 ping 和 traceroute 经常配合使用两个都装上心里才踏实。提示生产环境装包前先确认是否有内网镜像源。很多公司内网机器访问不了公网 apt/yum 源直接装会卡在下载。这种情况要么配置内网源要么用离线包安装。3.3 权限问题为什么有时要 sudotraceroute 需要构造原始套接字raw socket来发送自定义 TTL 的包这需要CAP_NET_RAW权限。普通用户默认没有这个权限所以直接运行会报socket: Operation not permitted。解决办法有两个一是用sudo traceroute二是给二进制文件加 capabilitysudo setcap cap_net_rawep $(which traceroute)加完之后普通用户也能直接跑。不过从安全角度生产环境不建议随便给二进制加 capability用 sudo 更稳妥。我一般是在个人开发机上加 capability 图方便服务器上老老实实用 sudo。4. 常用参数哪些必须掌握4.1 基础参数速查traceroute 的参数不少但日常真正高频使用的就那么几个。我整理了一张表按使用频率排序参数作用典型场景-n不解析域名直接显示 IP加快输出速度避免 DNS 拖慢-I使用 ICMP 探测UDP 被拦时改用-T使用 TCP 探测穿透防火墙最强-p指定目标端口配合-T指定 80/443-m设置最大跳数默认 30可调小加快结束-q每跳发送包数默认 3调成 1 加快输出-w等待响应时间秒默认 5网络慢时可调大-f设置起始 TTL跳过前面已知的跳-s指定源地址多网卡机器指定出口-n是我用得最多的参数。默认情况下 traceroute 会对每一跳的 IP 做反向 DNS 解析如果 DNS 服务器响应慢整个命令会卡很久。加上-n直接显示 IP输出快很多。排障时你关心的是 IP 和延迟域名解析纯属锦上添花。4.2 TCP 模式的实际用法TCP 模式是穿透防火墙的利器但用法有讲究。基本命令是sudo traceroute -T -p 443 example.com这里-p 443指定探测目标端口为 443。为什么选 443因为 HTTPS 流量几乎不会被防火墙拦截探测包能顺利到达目标。如果目标主机的 443 端口开着最后一跳会显示目标地址如果没开可能显示!R端口不可达或直接超时。有个细节要注意TCP 模式下中间路由器返回的仍然是 ICMP 超时消息只有最后一跳的响应取决于目标端口状态。所以即使目标端口没开你依然能看到中间路径只是最后一跳可能显示异常。4.3 组合参数实战实际排障时我常用的组合是sudo traceroute -n -T -p 443 -q 1 -w 2 -m 20 example.com拆解一下-n不解析域名-T -p 443用 TCP 探测 443 端口-q 1每跳只发 1 个包加快速度-w 2等待 2 秒默认 5 秒太长-m 20最多 20 跳默认 30 跳内网通常 20 跳内到。这个组合在跨机房排障时特别好用输出快、信息够。如果发现某一跳开始全是*再单独针对那一跳用默认参数-q 3 -w 5复测确认是偶发丢包还是持续不通。5. 输出解读从一堆数字里看出问题5.1 正常输出的结构先看一个典型的正常输出traceroute to example.com (93.184.216.34), 30 hops max, 60 byte packets 1 192.168.1.1 0.524 ms 0.498 ms 0.472 ms 2 10.0.0.1 2.134 ms 2.098 ms 2.156 ms 3 172.16.1.1 5.321 ms 5.287 ms 5.412 ms 4 203.0.113.1 12.456 ms 12.389 ms 12.501 ms 5 93.184.216.34 15.234 ms 15.198 ms 15.267 ms每一行的结构是跳数、路由器 IP或域名、三个 RTT 值。第一跳通常是你的网关192.168.1.1 这种私有地址最后一跳是目标主机。中间跳的 IP 可能是运营商或云厂商的路由器。判断路径是否正常主要看两点延迟是否逐跳递增以及是否有跳突然变大。正常情况下延迟会随着跳数增加而缓慢上升因为每经过一个路由器都要处理转发。如果某一跳延迟突然从 5ms 跳到 200ms说明那一跳附近有拥塞或跨了长距离链路。5.2 星号的含义输出里出现*是最常见的困惑点。*表示这一跳在等待时间内没有收到任何响应。可能的原因有该路由器配置了不响应 ICMP 超时消息很常见出于安全考虑探测包被防火墙丢弃网络拥塞导致响应超时该跳确实不可达关键判断如果*后面还有正常的跳说明路径是通的只是这一跳不响应而已。比如3 * * * 4 203.0.113.1 12.456 ms 12.389 ms 12.501 ms 5 93.184.216.34 15.234 ms 15.198 ms 15.267 ms第 3 跳全是星号但第 4、5 跳正常说明第 3 跳的路由器只是不响应探测路径本身没问题。这种情况不用管它。真正需要警惕的是从某一跳开始后面全是星号那才说明路径在那里断了。5.3 特殊标记的含义除了星号输出里还可能出现这些标记标记含义处理建议!H主机不可达目标主机不存在或网络不通!N网络不可达路由表里没有到目标的路径!P协议不可达目标不支持该协议!X通信被管理策略禁止被防火墙拦截!A与目标通信被管理策略禁止通常是 ACL 拦截看到!H或!N基本可以确定是路由或目标问题。看到!X或!A说明有防火墙策略在拦截需要检查安全组或 ACL 配置。6. 典型故障排查实录6.1 场景一能 ping 通但业务超时这是最经典的场景。ping目标能通但访问业务端口超时。这时候用 TCP 模式 traceroute 到业务端口sudo traceroute -n -T -p 8080 target-host如果 traceroute 能到达目标说明网络路径没问题问题在应用层服务没起、端口没监听、应用防火墙拦截。如果 traceroute 在某一跳断了说明网络层就有问题需要找网络团队排查那一跳。我遇到过好几次这种情况ping 通是因为 ICMP 被放行但业务端口被安全组拦了。用 TCP 模式一测最后一跳显示!X立刻定位到是安全组问题。6.2 场景二跨机房延迟高跨机房调用延迟高但不知道高在哪一段。用 traceroute 看每一跳的延迟sudo traceroute -n -T -p 443 -q 3 target-host重点看延迟在哪一跳开始明显上升。如果是在机房出口那一跳上升说明是机房出口带宽或链路问题如果是在中间某跳上升可能是运营商骨干网拥塞如果是在最后一跳上升可能是目标机房入口问题。有个经验跨运营商比如电信到联通的跳延迟通常会明显增加这是正常的互联互通问题不是故障。如果延迟在可接受范围内比如 50ms 以内不用太纠结。6.3 场景三间歇性丢包间歇性丢包最难查因为单次 traceroute 可能抓不到。这时候要多次运行对比结果for i in {1..10}; do sudo traceroute -n -T -p 443 -q 1 -w 2 target-host | tail -5 sleep 1 done连续跑 10 次看哪一跳经常出现星号或延迟飙升。如果某一跳反复出现高延迟那一跳就是瓶颈。如果每次丢包的跳都不一样可能是整体链路质量差需要联系网络团队。这种场景下mtr比 traceroute 更合适因为它会持续探测并统计每跳的丢包率。后面我会专门讲。6.4 常见问题速查表现象可能原因排查方向第一跳就全是星号本机防火墙拦截探测包检查本机 iptables/firewalld中间某跳星号但后续正常该路由器不响应 ICMP正常现象忽略从某跳开始全星号路径中断或防火墙拦截换 TCP 模式复测最后一跳显示!X目标防火墙拦截检查目标安全组/ACL延迟逐跳正常但业务慢应用层问题查服务日志、端口监听输出卡在 DNS 解析反向 DNS 慢加-n参数7. 和 mtr 配合使用效果更好7.1 mtr 是什么mtrMy Traceroute把 traceroute 和 ping 的功能合二为一。它持续向每一跳发送探测包实时统计每跳的丢包率和延迟。相比 traceroute 的“一次性快照”mtr 提供的是“持续监控”。安装方式和 traceroute 类似# Debian/Ubuntu sudo apt install mtr # CentOS/RHEL sudo yum install mtr基本用法mtr -n -T -p 443 target-host-n不解析域名-T -p 443用 TCP 探测 443 端口。运行后会进入交互界面实时刷新每跳的丢包率和延迟。7.2 用 mtr 定位丢包点mtr 的输出里Loss%列显示每跳的丢包率。判断丢包点的关键是从哪一跳开始丢包率突然上升并且后续跳都保持这个丢包率。比如HOST: localhost Loss% Snt Last Avg Best Wrst StDev 1. 192.168.1.1 0.0% 50 0.5 0.5 0.4 0.8 0.1 2. 10.0.0.1 0.0% 50 2.1 2.1 1.9 2.5 0.2 3. 172.16.1.1 20.0% 50 5.3 5.4 5.1 8.2 0.6 4. 203.0.113.1 20.0% 50 12.4 12.5 12.1 15.3 0.7 5. 93.184.216.34 20.0% 50 15.2 15.3 15.0 18.1 0.8第 3 跳开始丢包率 20%后续跳保持 20%说明丢包发生在第 3 跳附近。如果第 3 跳丢包 20% 但第 4 跳丢包 0%那第 3 跳的丢包只是它自己不响应探测不影响转发。这个判断逻辑很重要很多人看到中间跳丢包就慌其实要看丢包是否“传递”到后续跳。7.3 traceroute 和 mtr 的分工我的习惯是先用 traceroute 快速定位大致范围再用 mtr 持续观察确认。traceroute 适合一次性快速排查mtr 适合长时间监控和统计。两者配合基本能覆盖 90% 的网络路径问题。提示mtr 的-r参数可以生成报告模式输出适合脚本化采集。mtr -r -c 100 -n target会跑 100 次后输出统计报告方便存档对比。8. 几个容易踩的坑8.1 云环境的安全组拦截在云服务器上跑 traceroute最容易遇到的就是安全组拦截。云厂商的默认安全组通常只放行特定端口ICMP 和 UDP 高位端口经常被拦。这时候 traceroute 输出会大量出现星号让你误以为网络断了。解决办法优先用 TCP 模式探测 80/443 端口这两个端口通常放行。如果还是不行检查安全组的入站规则是否放行了 ICMP。有些云厂商的 VPC 内部路由也会拦截 TTL 超时消息这种情况 traceroute 基本没法用只能靠 mtr 或抓包。8.2 NAT 环境下的地址显示如果你的机器在 NAT 后面traceroute 第一跳可能显示的是 NAT 网关的地址而不是真实网关。这是正常的因为 NAT 会改写源地址。判断路径时从 NAT 网关之后的跳开始看即可。还有一种情况某些运营商级 NATCGNAT会导致 traceroute 显示的内网地址和实际不符。这种环境下排障比较困难建议直接联系运营商。8.3 反向 DNS 拖慢输出前面提过-n参数这里再强调一次。默认情况下 traceroute 会对每一跳做反向 DNS 解析如果 DNS 服务器响应慢或超时整个命令会卡很久。我见过一次 traceroute 跑了 3 分钟才出结果就是因为反向 DNS 超时。养成习惯排障时永远加-n。需要看域名的时候再单独去掉-n跑一次。8.4 权限和 capability 的坑给 traceroute 加 capability 虽然方便但系统更新后二进制文件被替换capability 会丢失又得重新加。所以如果依赖 capability记得在更新后重新设置。更稳妥的做法还是用 sudo。另外某些安全加固的系统比如启用了 SELinux 的 CentOS可能会限制 traceroute 的 raw socket 权限即使加了 capability 也不行。这种情况需要调整 SELinux 策略或者直接用 sudo 运行。9. 我个人的使用体会这些年排障下来traceroute 在我手里的定位很明确它是网络排障的第一把手术刀负责快速切开路径看断面。但它不是万能的遇到防火墙拦截、负载均衡、CGNAT 这些情况它的输出会有误导性。所以我的习惯是 traceroute 和 mtr 一起用traceroute 看快照mtr 看趋势再配合抓包tcpdump确认细节。最后分享一个小技巧如果你经常需要排查同一批目标可以把常用命令写成 alias 或脚本。比如我在.bashrc里加了alias trsudo traceroute -n -T -p 443 -q 1 -w 2 -m 20这样直接tr target-host就能快速跑一次 TCP 模式的 traceroute省去每次敲一长串参数。排障时时间宝贵能省一秒是一秒。另外traceroute 的输出建议保存下来。我一般会tee到文件sudo traceroute -n -T -p 443 target-host | tee /tmp/trace-$(date %Y%m%d-%H%M).log这样后续对比不同时间点的路径变化时有据可查。网络问题往往是间歇性的单次结果说明不了什么多次对比才能看出规律。