那一跳丢包96.7%,终点却一个包都没丢

那一跳丢包96.7%,终点却一个包都没丢
张文保 30 分钟阅读 1,310 阅读
本文目录
  1. 中间那一跳丢包96.7%,为什么终点一个包都没丢?
  2. 这张表在物理上自相矛盾
  3. 机制写在一份1995年的规范里
  4. 连这个回复本身都是可选的
  5. 同一台路由器,换个探针协议延迟为什么差29倍?
  6. 同一跳,两个数字
  7. 三种协议还会走出三条不同的路
  8. 为什么第2跳比第3跳还慢?
  9. 非单调是常态
  10. 倒数第二跳比终点还慢
  11. 连着跑三次,路径为什么每次都不一样?
  12. 一跳根本不是一台设备
  13. 多测几次的正确姿势
  14. 连续8跳全是星号,服务照样88毫秒
  15. 八跳全黑,终点全绿
  16. 这是最容易做错的一个判断
  17. 同一个终点,两个工具给出76和246毫秒,信哪个?
  18. 两个数字都是真的,问的问题不同
  19. 最差值那一列为什么会骗人
  20. 哪些数字才真的进了用户的等待时间?
  21. 一个三倍多的常数
  22. 这个常数是怎么来的
  23. 三个能进用户体验的数字
  24. 出海站真正该盯的是哪一跳?
  25. 那个158毫秒的台阶
  26. 能改的和不能改的
  27. 保哥读图的五步与一张判据表
  28. 五步
  29. 一张判据表
  30. 大包探测:什么时候值得单跑一次
  31. 给运维和运营各一句话
  32. 常见问题解答
  33. 中间跳丢包到底要不要管?一点都不用管吗?
  34. 为什么我在Windows上跑出来的结果跟Linux不一样?
  35. 看到路径里出现私有地址(10.x、192.168.x)是不是有问题?
  36. 连续统计模式跑多少轮才够?
  37. 路径追踪能看出对方用的是不是CDN吗?
  38. 那个三倍多的换算关系,在什么情况下会失效?
  39. 权威参考资料
摘要:连续跑了30个周期的路径统计,其中一条链路上第11跳和第13跳的丢包率都是96.7%,第14跳60%,而第15跳是0.0%,终点只有3.3%。这在物理上讲不通——如果第13跳真的丢掉了96.7% 的包,后面的跳不可能收得到。另一条链路更极端:连续8跳100% 无响应,终点丢包0%、平均91.5毫秒。同一台路由器,只把探针从UDP换成ICMP,延迟从45.1毫秒变成1.5毫秒,差29倍。这些数字全部指向同一个结论:中间跳的延迟和丢包,测的不是数据在转发,是那台路由器愿不愿意抽空回你一条ICMP。

出海站的运营和运维之间有一段经典对话。运营说欧洲客户反馈打不开,运维跑一条路径追踪,截图发过去,图上第12跳标着红色的180毫秒和40% 丢包。于是双方达成共识:问题出在中间某个运营商身上,找线路商去。

这个结论有相当高的概率是错的,而且错得很有迷惑性——因为那个红色数字确实存在,确实是工具打出来的,只是它测的东西跟大家以为的不是一回事。

下面所有数字来自2026年7月31日同一小时内、从同一台国内服务器打出去的实测,目标是三个在国内访问频次都很高的境外站点。

中间那一跳丢包96.7%,为什么终点一个包都没丢?

先看最刺眼的那一组。用连续统计模式跑30个周期,去往某CDN厂商官网的路径上,逐跳丢包率是这样的:

跳号丢包率平均延迟(毫秒)这一跳在哪
80.0%2.4机房出口
990.0%2.6城域网
1196.7%2.2省网
1273.3%5.1省网
1396.7%5.9骨干网入口
1460.0%7.2骨干网
150.0%165.4出境
173.3%163.9对方网络
18(终点)3.3%349.3目标服务器

这张表在物理上自相矛盾

把第13跳和第15跳放在一起看:第13跳丢了96.7% 的包,也就是30个探针只有1个活着通过;而第15跳丢包0.0%,30个探针一个不少全部返回。

第15跳的包必须先经过第13跳。如果第13跳真的在丢包,第15跳不可能是零丢包。数据不会绕过中间那台设备自己飞过去。

所以这张表上唯一自洽的解释是:第13跳根本没在丢包,它只是没有回复那些专门发给它的探针。它照常转发了所有过路的数据,只是懒得给你回执。

同一份实测里另外两条链路完全是同一个形状。去往某电商SaaS平台的路上,第9跳93.3%、第14跳93.3%、第15跳83.3%、第16跳46.7%,而夹在中间的第17跳是0.0%,终点23.3%。去往某代码托管平台的路上,第11跳96.7%、第13跳93.3%、第14跳73.3%,后面的第17、18跳全是0.0%。

三条完全不同的路径,中间高丢包、后面零丢包这个矛盾在每一条上都成立。这就不是巧合,是机制。

机制写在一份1995年的规范里

路径追踪这类工具的工作方式是:故意把数据包的TTL设成1、2、3……,让它在第N跳上耗尽,逼那台路由器回一条ICMP超时消息,从而暴露自己的地址。整套把戏建立在路由器愿意回这条消息上。

RFC 1812第4.3.2.8节对ICMP速率限制的要求把这件事说得非常直白,原文是:

A router SHOULD also be able to limit the rate at which it sends other sorts of ICMP error messages (Destination Unreachable, Redirect, Time Exceeded, Parameter Problem).

括号里列的四种消息中,Time Exceeded正是路径追踪赖以工作的那一条。规范要求路由器应当有能力限制它的发送速率,并且紧接着解释了理由:

Two problems for a router sending ICMP error message are: (1) The consumption of bandwidth on the reverse path, and (2) The use of router resources (e.g., memory, CPU time)

两条理由都很硬:回一条ICMP要占用回程路径的带宽,还要消耗路由器的内存和CPU。而路由器的本职工作是转发,转发跑在专门的硬件上,生成ICMP却要惊动主控CPU。在一台每秒转发几千万个包的核心设备上,为了让某个人看清路径而去中断CPU,这笔账怎么算都不划算。

更妙的是规范接下来那句:限制怎么施加,“is left to the implementor's discretion”——留给实现者自行决定。也就是说每个厂商、每台设备、每个网管的限速策略都可能不一样,你测出来的丢包率是这台设备当时的心情,不是一个可比的指标。

连这个回复本身都是可选的

再往前追一层,事情更彻底。RFC 792对Time Exceeded消息的定义写于1981年,关于TTL归零时该做什么,原文是:

If the gateway processing a datagram finds the time to live field is zero it must discard the datagram. The gateway may also notify the source host via the time exceeded message.

丢弃数据包是 must,通知源主机是 may路径追踪这个工具存在了四十多年,它能看见中间跳这件事,从规范第一天起就是路由器的自愿行为。

知道了这一点,中间跳那些红色数字就该换个读法了:它们描述的是“这台设备对探针的配合程度”,跟“数据能不能过去”是两个正交的维度。

同一台路由器,换个探针协议延迟为什么差29倍?

如果上一节还留有“也许真是网络不好”的余地,这一组对照实验能把它彻底堵死。

同一跳,两个数字

对同一个目标,用三种探针协议各跑一次,间隔不到一分钟。第2跳是同一台设备(机房网关,地址完全相同),三次测到的延迟是:

探针协议第2跳延迟(三个探针,毫秒)
默认UDP45.136 / 45.157 / 45.215
ICMP(-I)1.534 / 1.620 / 1.780
TCP 443(-T)1.462 / 1.527 / 1.652

同一台设备、同一分钟、同一条链路,UDP探针报45毫秒,另外两种报1.5毫秒,相差29倍

这45毫秒不是网络延迟。这台设备对UDP探针的ICMP回复排在了一个更低的优先级队列里,或者干脆走了一段限速逻辑,于是回执晚了43毫秒才出来。数据转发本身没有任何变化——三次测量里,它后面的所有跳都是正常的个位数毫秒。

更能说明问题的是三次测量的内部一致性:UDP那三个探针是45.136、45.157、45.215,彼此只差不到0.1毫秒。如果这是链路拥塞,三个探针不该这么整齐;这么整齐的数字,更像是一个固定的处理延迟,而不是排队等待。

三种协议还会走出三条不同的路

换协议影响的不只是数字,连路径本身都会变。同一个目标,三次测量的结果:

探针协议解析到的目标IP可见跳数星号跳的位置
默认UDP172.64.145.9319第6、9、10跳
ICMP172.64.145.9319第6、9、10、11、14、15、16跳
TCP 443104.18.42.16319第5、6、7、10、12、14、16跳

先看最后一行:TCP那次追的根本不是同一台服务器。目标域名的DNS返回了不同的地址,三次测量里出现了两个不同的目标IP。这类大站前面挂着任播网络,同一个域名在不同时刻解析到不同地址是常态。

再看星号的分布:ICMP那次有7跳无响应,UDP那次只有3跳。同一段物理链路,换个探针协议,“看不见”的路由器数量翻了一倍多。

为什么会这样,traceroute手册页对各种探针方式的说明里有答案:默认的UDP方式往一个不太可能被占用的高端口发包,ICMP方式发Echo请求,TCP方式发SYN包。中间路由器和防火墙对这三类流量的策略完全独立,某台设备可能放行TCP 443却丢弃UDP高端口,也可能反过来。

由此得到一条相当实用的判据:如果你的业务跑在HTTPS上,就该用TCP 443的探针来追路径。它走的端口跟真实流量一致,途中的策略也就跟真实流量一致;用默认UDP追出来的那条路,可能根本不是你的用户在走的那条。

为什么第2跳比第3跳还慢?

大部分人心里对路径追踪的输出有一个默认模型:延迟应该逐跳递增,因为距离越来越远。这个模型不成立,而且不成立得相当频繁。

非单调是常态

还是那次UDP测量,前八跳的原始数字:

跳号延迟(毫秒)与上一跳相比
12.445
245.136+42.7
35.123−40.0
45.767+0.6
58.416+2.6
76.425−2.0
81.968−4.5

第3跳比第2跳快40毫秒,第8跳比第7跳快4.5毫秒,第8跳甚至比第1跳还快。数据当然没有倒着流。

原因很直接:每一跳的数字是一次独立的往返测量,它们之间没有任何包含关系。第3跳的5.123毫秒是“从我这里到第3跳再回来”的完整耗时,跟第2跳那次测量是两件独立的事。第2跳那台设备回执慢,只影响第2跳这一个数字,不会传递给后面。

所以正确的读法是:把每一行当成一次独立实验的结果,而不是一条流水线上的累计刻度。一行的数字异常,只说明那一行对应的那台设备回执异常。

倒数第二跳比终点还慢

另一条链路上出现了更反直觉的一组:第17跳的三个探针是286.348、272.686、342.695毫秒,而第18跳(终点)是176.854、160.417、252.983毫秒。倒数第二跳比终点慢了大约1.6倍。

这里除了前面说的独立测量之外,还多了一层原因:ICMP差错消息的回程路径,跟正常数据的回程路径可能完全不同。RFC 1812那段解释里第一条理由就点明了ICMP要消耗“reverse path”的带宽——规范自己承认这条消息走的是回程

互联网上去程和回程走不同路线是常态,不是异常。这意味着你在图上看到的每一个中间跳延迟里,都混着一条你完全看不见的回程路径。你以为在测一条线,其实每一行都在测两条不同的线的总和,而且每一行的那两条线还各不相同。

连着跑三次,路径为什么每次都不一样?

同一条命令,同一个目标,连着跑三次,中间不停顿。按直觉三次结果应该几乎一致,实际上:

第1次第2次第3次
总跳数191920
目标IP172.64.145.93104.18.42.163172.64.145.93
第12跳地址119.147.220.141119.147.220.137119.147.222.45
第15跳地址202.97.35.102202.97.81.182110.94.123.118
能看见的跳数131516

跳数变了,目标变了,中间几乎每一跳的具体地址都变了。三次测量里,只有前八跳(机房内和城域网那段)是稳定的。

一跳根本不是一台设备

还有更直接的证据。某一次测量的第11跳,三个探针返回了三个不同的地址:

11  219.133.32.157  3.060 ms
    219.133.32.145  2.249 ms
    219.133.32.137  2.744 ms

同一跳、同一次命令、三个探针,撞上了三台不同的路由器。第13、14跳也是同样的形态。

这就是等价多路径在起作用。RFC 2992对等价多路径算法的分析描述了最常见的一种实现:路由器对能标识一条流的包头字段做哈希(文中举的例子是CRC16),再用哈希结果落进哪个区间来决定走哪条下一跳。

关键在于哪些字段参与哈希。路径追踪的每个探针为了区分回执,会用不同的源端口或序号——而端口正是标识流的字段之一。于是每个探针算出来的哈希值不同,被分配到不同的下一跳,你看到的“这一跳有三个地址”就是这么来的。

由此得到第二条判据:中间跳的具体地址对做业务的人几乎没有诊断价值。它每次都不同,你也没法要求对方按某一条固定路线走。真正稳定、真正可比的只有两样东西——终点的延迟,和相邻跳之间的延迟增量落在哪一段

多测几次的正确姿势

既然单次不可靠,正确做法是把重复测量交给工具而不是自己反复敲命令。mtr官方项目页介绍的正是这个思路:它把路径追踪和持续探测合成一件事,连续发很多轮并给出每一跳的丢包率、最好值、最差值和标准差。

但要记住前面两节的结论:它给出的中间跳统计仍然是“对探针的配合程度”的统计,多测几十轮只会让这个不可靠的数字变得更精确,不会让它变得更有意义。多测的真正价值在终点那一行——终点的丢包率和延迟分布,是唯一直接对应用户体验的数据。

连续8跳全是星号,服务照样88毫秒

这一节只有一组数字,但它可能是整篇里最该记住的一组。

八跳全黑,终点全绿

去往某代码托管平台的连续统计,尾部是这样的:

跳号地址丢包率平均延迟(毫秒)
2051.10.10.1306.7%116.7
21无响应100.0%
22无响应100.0%
23无响应100.0%
24无响应100.0%
25无响应100.0%
26无响应100.0%
27无响应100.0%
28无响应100.0%
29(终点)20.205.243.1660.0%91.5

连续8跳彻底无响应,紧接着终点零丢包、平均91.5毫秒、标准差只有3.6毫秒。这条链路的健康程度是全场最好的三条之一。

那8跳是对方数据中心内部的网络。大型云平台的内部设备通常统一关闭ICMP差错消息生成,这是一条常规的安全与性能策略,不是故障。

这是最容易做错的一个判断

如果你用的是普通的路径追踪命令,默认最大跳数是30;而我这次为了控制耗时把上限设成了24。结果是命令跑到第24跳时全是星号就停了,看上去像是“路径在第21跳断了,根本到不了目标”。

同一时刻,用命令行去请求这个站的首页,首字节0.5055秒,一切正常。

所以这条判据要单独立出来:路径追踪追不到终点,跟服务不可达是两件完全无关的事。判断一个站通不通,唯一可靠的办法是直接发一个真实的业务请求过去。用什么工具去发、发出去之后哪些数字才可信,curl -I查了一圈说这站没配缓存头,换成GET之后那五个头全在那篇拆得比较细。

顺带一提,这台服务器上默认根本没装路径追踪工具,只有一个功能受限的替代品,跑这批实测之前得先装。真到了要排障的时候,先确认手上有没有工具,比什么都实际。网卡、端口、路由表这些更基础的东西该怎么看,Linux网络配置和排查怎么做才不瞎猜那篇把常用命令过了一遍,可以当装机后的第一份清单。

同一个终点,两个工具给出76和246毫秒,信哪个?

上一节说“只看最后一行”,但最后一行本身也有讲究。同一个目标、同一小时内,三种工具给出的数字是这样的:

测量方式终点读数(毫秒)
路径追踪(UDP探针)246.055
路径追踪(ICMP探针)246.081
路径追踪(TCP 443探针)242.504
连续统计的最好值76.3
连续统计的平均值228.0
持续探测20次的平均值230.4
持续探测20次的最小值66.5

两个数字都是真的,问的问题不同

246和76之间差了3.2倍,但没有哪个是测错的。

路径追踪那三个246是单次采样,三种协议高度一致,说明这个值很稳定——它稳定地反映了“这一刻这条链路的实际表现”。而76.3是三十次采样里的最好那一次,它回答的是另一个问题:“这条链路在完全没有干扰时能跑多快”。

两个数字合起来才有意义:物理下限76毫秒,实际表现230毫秒,中间那154毫秒是排队、限速和拥塞吃掉的。这个差值才是可优化空间,而单看任何一个数字都看不到它。

对照另外两个目标,这个差值的分布很不一样:某代码托管平台最小88.4、平均92.2,差值只有3.8毫秒;某CDN厂商官网最小164.6、平均359.4,差值194.8毫秒。前者是一条几乎跑满物理极限的干净链路,后者的实际表现只有理论能力的一半不到。

最差值那一列为什么会骗人

连续统计模式会给出最好值、平均值、最差值和标准差四列。最差值那一列几乎没有诊断价值,而且经常主动误导。

实测里最典型的一行是某条路径的第4跳:

统计量数值(毫秒)
最好值3.1
平均值19.9
最差值470.8
标准差85.3

三十次采样里有一次跑出了470.8毫秒,是最好值的152倍。这一次异常把平均值从3点几拉到了19.9,整整抬高了六倍。如果你只看平均值那一列,会得出“这台机房内的设备有问题”的结论;实际上另外二十九次全在3毫秒附近。

另一条路径的第8跳是同一个形状:最好1.9、平均7.7、最差162.8、标准差29.3。同样是一次异常拉高了整列。

所以四列的正确用法是:最好值判断链路能力,标准差判断稳定程度,平均值只在标准差很小的时候才可信,最差值除了提醒你“存在过一次异常”之外没有别的用途——尤其不能用来跟别的链路做比较。

单次测量里同样会撞上这种异常。某次TCP探针测到终点时,三个探针分别是262.434、1445.124、391.731毫秒——中间那个1.45秒比同一行的另外两个高出4到5倍。如果那一行只发了一个探针,而恰好是这一个,你会得到一个完全失真的结论。

这就是为什么每跳默认发三个探针,也是为什么把探针数调成1来提速是个坏主意:省下来的那几秒,代价是把单点异常直接变成了唯一的结论。真要提速,减少最大跳数比减少每跳探针数安全得多。

哪些数字才真的进了用户的等待时间?

前面拆了一堆“不能信”的数字,那么该信什么?答案是终点的往返时间,而且它跟用户体验之间有一个相当稳定的换算关系。

一个三倍多的常数

同一批目标,同一小时内,用两种方式各测一次:一次纯网络层的往返时间,一次完整的HTTPS首字节。把首字节扣掉DNS解析的固定开销之后,两者相除:

目标站往返时间均值(秒)首字节扣除DNS后(秒)倍数
某代码托管平台0.09220.29883.24
某电商SaaS平台0.23040.79653.46
某CDN厂商官网0.35941.25223.48

三个站分别在三个不同的大洲、挂着三家不同的基础设施,倍数全部落在3.24到3.48之间。我第一次算出来的时候复算了两遍。

这个常数是怎么来的

它不是巧合,是握手结构决定的。一次HTTPS请求在第一个字节回来之前,至少要走这么几趟:

  • TCP三次握手:1个往返。
  • TLS握手RFC 8446定义的TLS 1.3完整握手把这一步压到了1个往返(老的TLS 1.2需要2个)。
  • 发请求、等首字节:1个往返,再加上服务器自己的处理时间。

1加1加1等于3,剩下的零点二几就是服务器处理和各种零碎开销。三个站的实测值全部略高于3,正好对应这个结构。

这条换算关系的实用价值非常直接:你在网络层省下的每1毫秒,用户端会体感到大约3.3毫秒。反过来说,一条比现在快50毫秒的线路,能给首字节带来大约165毫秒的改善。这个杠杆比大多数人估计的要大,也解释了为什么出海站换线路的收益经常超出预期。多层缓存怎么在这个基础上继续往下压,TTFB怎么优化才不白费:多层缓存如何同时左右Core Web Vitals与Google抓取那篇算过完整的账。

三个能进用户体验的数字

把可信的数字收拢成一张短表,其余的都可以先放一边:

数字怎么取说明什么
终点往返时间的最小值连测20次以上取min这条链路在无干扰时的物理下限,换线路能改善的就是它
终点往返时间的标准差同上取mdev抖动大小,直接影响用户感受到的稳定程度
终点丢包率同上唯一有意义的丢包数字,会触发重传并放大延迟

三个目标的实测对照很能说明问题:某代码托管平台最小88.4毫秒、标准差只有3.75毫秒、丢包10%;某CDN厂商官网最小164.6毫秒、标准差72.6毫秒、丢包0%。前者延迟低但会丢包,后者不丢包但抖动是前者的19倍。这两种问题对用户的影响完全不同,得分开治。

出海站真正该盯的是哪一跳?

答案是:不盯任何一跳,盯相邻两跳之间的增量,而且只有一个位置的增量真正重要。

那个158毫秒的台阶

去往某CDN厂商官网的路径上,把每一跳跟上一跳的延迟差列出来:

跳号延迟(毫秒)增量
112.414
125.086+2.7
135.898+0.8
147.290+1.4
15169.376+162.1
16161.761−7.6
17286.348+124.6
18(终点)176.854−109.5

整条路径上只有一个位置发生了量级跳变:第14跳到第15跳,从7.3毫秒跳到169.4毫秒。这一跳就是出境。它之前的所有跳加起来只有7毫秒,之后的所有跳再怎么折腾也是在160到350毫秒之间晃。

换个说法:这条链路上96% 的延迟由一个动作产生,就是跨过国境线。国内那14跳无论怎么优化,最多也就是从7毫秒降到5毫秒,改善不到1.2%。

第17跳那个286毫秒和第18跳回落到176毫秒的组合,前面已经解释过——独立测量加上不同的回程路径,不代表第17跳出了问题。

能改的和不能改的

把这条路径按“你能不能动它”重新切一遍,结论就很清楚了:

路段本例耗时你能做什么
机房内 + 城域网(第1到8跳)约2.4毫秒几乎无事可做,占比可以忽略
省网 + 骨干网(第9到14跳)约5毫秒换机房/换运营商,收益个位数毫秒
出境这一跳约158毫秒换出口线路、上加速节点、或者把服务放到境外
境外段(第15跳之后)约10毫秒选离用户更近的节点

这张表解释了一个常见的困惑:为什么给国内机房做了一堆优化,海外客户还是觉得慢。因为你优化的那部分总共只占5%。真正的做法只有把服务或缓存节点搬到用户那一侧,这件事的完整决策链条,外贸独立站用国内主机还是国外主机?备案、速度与合规那篇按备案、速度、合规三条线拆过。

如果站已经在境外、海外客户仍然说慢,那就得往别的方向查了——DNS解析、边缘节点覆盖、乃至客户端设备本身都可能是原因,海外用户说独立站打不开、加载慢?从DNS、线路到CDN的网络层排障那篇给了一条完整的排查顺序,而弱网和低端机这一侧的影响,海外客户用低端机、弱网打开你的独立站有多卡那篇量过。

保哥读图的五步与一张判据表

把前面所有结论压成一套可以照着做的流程。这套东西我现在给客户看路径图之前会先自己走一遍。

五步

  1. 先看最后一行,别看中间。终点的延迟、丢包、抖动是唯一直接对应用户体验的数据。中间行先当作背景噪声。
  2. 用跟业务一致的探针协议。业务跑HTTPS就用TCP 443探针,别用默认的UDP。协议不一致,路径和策略都可能不一致。
  3. 连测二三十轮,看分布不看单次。取最小值判断链路能力,取标准差判断稳定性,单次结果只能当参考。
  4. 找增量最大的那一跳,那才是瓶颈的位置。不看绝对值,看相邻两跳的差。跨境链路上通常只有一个台阶是重要的。
  5. 用真实业务请求做交叉验证。路径图说不通的地方,发一个真实请求过去,以业务请求的结果为准。

一张判据表

你在图上看到大概率的真相该做什么
中间某跳丢包50% 以上,后面的跳正常ICMP限速,转发没问题忽略,继续看终点
连续多跳全星号,终点正常对方网络关闭了ICMP生成忽略
某跳延迟高,后面的跳反而低那台设备回执慢,不是链路慢忽略
某跳之后所有跳延迟都抬高一个量级真瓶颈,通常是出境或跨洲这才值得动
终点丢包高真丢包,会触发重传换线路或换节点
终点延迟稳定但绝对值高物理距离,改不了把服务搬近用户
终点标准差大拥塞或多路径抖动换线路,或看是否分时段
路径追不到终点,但业务请求正常不是问题忽略

大包探测:什么时候值得单跑一次

路径追踪命令后面可以跟一个字节数,用来指定探针包的大小。默认是60字节,几乎不可能触发任何与包大小有关的问题。用1400字节再跑一次,是排查一类特定故障的标准动作。

本次实测跑了一组1400字节的探针,结果是整条路径与60字节时形态一致,所有能响应的跳都正常响应,终点也照常到达。结论是这条链路上没有分片相关的问题,可以把这个方向排除掉。

什么时候需要跑这一趟:症状是“小请求正常、大传输卡死”。比如打开首页很快、提交一个带附件的表单就一直转圈;或者接口的短响应正常、返回大JSON就超时。这类症状的典型成因是路径上某处的最大传输单元比两端以为的小,而用来协商这件事的ICMP消息又被中途丢掉了——注意,被丢掉的又是ICMP,跟本文前面讲的是同一批消息、同一批原因。

反过来说,如果你的症状不是“大小相关”,跑大包探测意义不大,60字节的默认值已经够用。这是一个用来证伪特定假设的工具,不是常规体检项。

给运维和运营各一句话

给运维的:把路径图发给客户之前,先自己检查一遍中间跳的丢包和后面跳的丢包是否自相矛盾。矛盾就说明那些红色数字不能作为证据,发出去只会把排查方向带偏,回头还得自己收拾。

给运营的:当技术同事拿着一张标红的路径图说“问题在中间某个运营商”时,问一句“终点丢包多少”。如果终点丢包接近零,那张图就不足以支撑这个结论。至于服务器本身是不是真的扛不住,那是另一条完全不同的排查线,Linux服务器突然变慢、负载飙高怎么排查那篇讲的是那一侧。而证书这类会在握手阶段拖慢首字节的东西,证书有效期正在砍向47天,一年一换的续期流程撑不到2027年那篇里有一部分相关内容。

常见问题解答

中间跳丢包到底要不要管?一点都不用管吗?

有一种情况要管:某一跳丢包高,并且它后面的所有跳丢包也都高。这时候丢包是往下传递的,说明是真的在丢。判据就是看传递性——真丢包会一路传到终点,假丢包只在自己那一行出现。本文实测的三条链路全部属于后者,中间高丢包后面立刻回到零。另外如果你就是那台设备的管理者,中间跳的读数对你有意义;对使用者来说没有。

为什么我在Windows上跑出来的结果跟Linux不一样?

因为默认探针协议不同。Windows自带的那个命令默认用ICMP,Linux上的默认用UDP高端口。前面那组29倍的差距就是这么来的——不是两个系统测得不准,是它们在问两个不同的问题。要让两边可比,在Linux上加参数切到ICMP模式即可。更实际的建议是两边都用TCP加业务端口,这样测的才是你真正关心的那条路。

看到路径里出现私有地址(10.x、192.168.x)是不是有问题?

不是。本文实测的路径里第3到第7跳全是私有地址,那是机房和运营商内部的转发设备,用私有地址编址是很常规的做法。这些地址不会出现在公网路由表里,也不影响数据转发。真正需要注意的是另一种情况:路径走到一半又绕回一个你熟悉的国内地址,那可能说明流量被牵引了,值得看一眼。

连续统计模式跑多少轮才够?

看你要回答什么问题。判断链路能力,二三十轮就够了,因为最小值收敛得很快。判断稳定性和丢包率,轮数越多越准,一两百轮更可靠。判断是不是分时段的问题,那就不是靠加轮数解决的,得改成每小时跑一次、连跑一整天。有一点要注意:轮数越多,被对方的防护策略盯上的概率越大,实测里就遇到过连续请求之后目标站开始拒绝响应的情况。

路径追踪能看出对方用的是不是CDN吗?

能看出一些线索但不可靠。比较明显的信号是最后几跳的地址属于知名基础设施厂商的地址段,以及同一个域名多次解析到不同IP。但反过来不成立——看不出这些线索不代表没用CDN。更直接的办法是查这个域名的解析记录指向哪里,以及看响应头里有没有边缘节点留下的标记,那比从路径上猜准确得多。

那个三倍多的换算关系,在什么情况下会失效?

至少三种情况。一是连接复用:如果客户端已经和服务器建立了连接(比如同一个页面的第二个请求),握手那两个往返就省掉了,倍数会掉到接近1。二是服务器处理时间很长:如果后端要跑一个几百毫秒的查询,那部分是加在末尾的常数,不随往返时间缩放。三是TLS 1.2或者会话恢复:前者多一个往返,倍数会升到4以上;后者少一个往返,倍数会掉到2出头。把这三种情况排除掉,剩下的场景里这个换算是相当稳的。

权威参考资料

分享到
标签
版权声明

本文标题:《那一跳丢包96.7%,终点却一个包都没丢》

本文链接:https://zhangwenbao.com/traceroute-intermediate-hop-latency-loss-misread.html

版权声明:本文原创,转载与引用请注明作者与原文链接。许可协议: CC BY 4.0

继续阅读
发表评论
分享到微信 或在下方手动填写
支持 Ctrl + Enter 提交