是它挂了,还是只有你?

多观察点检查从其他人的网络、其他国家中的探针上,在你从自己网络运行它的同一时刻,运行同一个测试——一次 ping、一次 HTTP 请求、一次 DNS 查询。这一处改变把一个无从回答的问题(“我这儿能用——还有别人也这样吗?”)变成了一个对比:如果每个观察点都失败,目标就是挂了;如果只有你的失败,问题就住在你与它之间的路径上。本指南讲清单个第二观察点到底能证明什么、人人都会踩一次的 anycast 陷阱,以及如何用本站的全球 ping 来做这个检查。

“我这儿能用”的问题

每个事故频道都在同一小时内听过这两句话:“站点挂了”和“我这儿能用”。它们可以都是诚实的报告。从单个观察点——你的笔记本、你的办公室、一台监控机——运行的一次测试,测量的恰恰只有一件事:那一个网络、在那一条路径上、在那一个时刻的体验。它分不清一个对所有人都挂了的服务,和一条只对你断了的路径:一个生病的传输提供商、一条区域性过滤规则、一个返回被污染或陈旧答案的 DNS 解析器、一场发生在三张网络之外、你从未听说过的对等纠纷。从单个观察点内部看,这些全都长得一模一样——一个没有回邮地址的失败。

工单和状态页受着同样的几何之苦。状态页说“运行正常”,因为提供商自己的探针——坐在提供商自己的邻里里——能顺利到达服务,而一整个地区到不了。用户报告“挂了”,因为他们的 ISP 把流量黑洞了,而服务正哼着歌运转。两边都没有撒谎;两边都在从一把椅子上做概括。修法不是从同一把椅子上做更精确的测量。而是更多的椅子。

第二个观察点能证明什么

在其他网络上加上探针——其他自治系统、其他国家、其他种类的连接——并从它们全部同时运行完全相同的测试。现在模式自己会争辩。如果三个洲、五张网络上的探针在同一时刻以同样的方式全部失败,共同因素就是目标:服务、它的主机、或它自己的网络挂了,再多的本地摆弄也改变不了这一点。如果四个成功而只有最接近你处境的那个探针失败——或者只有你失败——共同因素反转:目标是活着的,断裂在失败的观察点所共享的路径上的某处。独立观察点之间的一致,是“它挂了吗?”这个问题能得到的最接近证明的东西。

本站使用的探针属于由 jsDelivr 运行的 Globalping 网络:数千个由全世界志愿者托管的小型软件探针,从数据中心服务器到家庭连接都有,它们接受标准化的测量——ping、traceroute、MTR、DNS 和 HTTP——并报告它们所看到的。价值不在任何单个探针;一个城市里的一台志愿者机器只是一个轶事。价值在于这些轶事是独立的:不同的网络、不同的上游、不同的故障模式,全都在同一时刻回答同一个问题。

anycast 与 CDN 的注意事项

陷阱在这里,人人都会踩一次:来自不同地方的不同答案可以全部都是对的。现代服务不是一个地方的一台机器。Anycast 从许多位置通告同一个地址,所以法兰克福的一个探针和圣保罗的一个探针向“同一个” IP 发包时,谈话的是不同的物理边缘,可能在不同的基础设施大陆上——一个健康,一个正在重启。CDN 把每个客户端引向附近的边缘,而一个边缘可以在一个地区挂掉、服务在其他地方却完美无缺。探针之间的分歧并不自动等于矛盾;对一个 anycast 目标来说,分歧正是设计在按意图工作,问题也随之变成“在哪里挂了?”而不是“挂了吗?”。

DNS 从另一面说明同一点。权威服务器和解析器按设计给出不同答案——GeoDNS 返回“最近”边缘的地址,EDNS 客户端子网让解析器可以代表你的邻里提问,所以东京的一个探针解析器和得克萨斯的一个解析器会合理地为同一个名字收到不同地址(当问题是世界持有的是哪些记录时,用 DNS 传播检查器把它们并排比较)。来自不同探针的不同地址不是不一致的证据。它们是那个名字正在做本地化的证据——并且它们告诉你每个地区的用户实际会遇见哪个边缘。

选能回答问题的那种测量

全球 ping 提供五种测量类型,选得好比跑得多更重要。每一种回答不同的问题,跑错一种会得到对你没问过的东西的自信答案。在看任何人的结果之前,先把类型与症状对应好。

Ping 回答最窄的问题:目标从这里可达吗,路上丢了多少?它是“这个网络到底能不能看见那台主机”的正确测试,也是对应用层任何事情的错误测试——一台主机可以在它的 Web 服务已死时仍然回答 ping。HTTP 回答用户的问题:一次真实的请求从那里能成功吗,状态码是什么,整件事花了多久?当争论是“站点能用/站点不能用”时,来自多个探针的 HTTP 是双方都该接受的证据。DNS 回答命名问题:每个地区实际为这个名字拿到哪些地址?它是你区分“服务挂了”和“我所在的地区被送往已死的边缘”的方法。

Traceroute 回答在哪里的问题:一跳一跳地,从这个探针到目标的路径在哪里停住、卡住、或拐向意想不到的地方?请从失败的那个观察点运行它,而不是从一个能用的观察点。MTR 是随时间推移的 traceroute——同一条路径被反复探测,于是丢失和延迟以速率而不是一个冻结样本的形式按跳显示;它是为“它间歇性地坏”准备的工具,那时单次 traceroute 抓到的恰是路径表现良好的一天。五种测量共同的纪律是:先判定你在测哪种故障,选那一种能看见它的测量,让其他测量等一等。

读结果而不自欺

先分开人们习惯性合并的两个数字。丢失——从未回来的请求——是损害;延迟——慢慢回来的请求——是不适,而两者的成因和修法不同。一个显示 100% 丢失的探针找到了一堵墙;一个显示零丢失和高延迟的探针找到了一条长路或拥堵的路,把后者报告成“挂了”正是健康服务被半夜叫醒的原因。然后做同类比较:以中位数探针为故事,而不是最好的,也不是最差的。一个探针返回一个离谱的离群值——巨大的延迟、一个别人都没见过的超时——那是关于那个探针的那一刻、它的主机、或它的上游的陈述。只有当独立的探针与它一致时,它才成为关于目标的证据。

也请留意记账。一个探针报告目标“离线”、而它的邻居们都成功时,它最可能报告的是它自己——一个崩掉的探针、一段断掉的家庭连接、一个本地过滤器——而志愿者探针这些都有;这是一个没人集中运营的网络的代价。记下时间戳,并把陈旧的或缓存的结果当作历史,而不是新闻。而当每个探针都一致认为目标活着、你的用户却依旧到不了时,两边都信:你已经学到故障是真的、而且是窄的——它住在一条你的探针碰巧都没有共享的路径上,这是一个发现,不是一个矛盾。

诚实的限制

探针是志愿者,网络的行为也像个志愿者网络。探针来来去去——一个今天早上还可用的位置今晚可能就离线,覆盖在一些国家稠密、在另一些国家稀薄到不存在,而且你不能因为你的用户在那里就要求某个具体 ISP 内部的一个探针。探针们也大多坐在数据中心和爱好者连接上,而不是你的真实用户浏览时用的住宅和移动网络;一个数据中心探针证明服务从连接良好的地方可达,这涵盖了问题的大部分,但不是问题的全部。把这张地图当作世界网络的一个慷慨绘制的样本——而不是世界本身。

本站对这个网络的使用是刻意克制的:它运行在 Globalping 的匿名、共享免费层上,所以检查带有每位访客的限额,结果会被短暂缓存,而不是猛敲一份志愿者资源——如果一个检查请你等一等,那是共享层正在被共享。在这些限制内,工作模式是:先在这里跑多观察点检查来定清“挂了还是只有我”,然后对胜出的那一方深入——用网站健康检查看一次对站点的详细审视能告诉你的一切,并且在你改动了什么之后,再从全球 ping 跑一轮新的。对所有人挂了和只对你挂了需要不同的下午;十分钟别人的观察点,就是你弄清自己正在过哪种下午的方法。

常见问题

我应该从多少个位置测试?

这个工具每次检查最多运行四个位置,而选得好的四个胜过随便选的四十个。挑与争论相配的一组分布:一个靠近你自己用户的探针、一个在另一个洲的、一个靠近目标托管地的,以及一个远处的作为对照。如果近的和远的探针一致,你就有了答案;如果只有近的失败,你也同时定位了问题。更多位置主要在前四个以你尚读不懂的模式不一致时才有帮助。

一个探针说离线——站点挂了吗?

仅凭那个证据不能。单个探针自己也可能离线——崩掉了、断线了,或在它自己的一个过滤器后面——而志愿者探针没有运营者在为它们担保。“挂了”是一个你从一致中得出的结论:几个独立的探针,在不同的网络上,在同一时刻以同样的方式失败。一个探针失败而它的邻居成功,告诉你的是那个探针的路径,诚实的报告是“从那一个观察点不可达”,而不是“挂了”。

为什么同一个域名从不同探针解析出不同地址?

因为它本该那样工作。GeoDNS 和 EDNS 客户端子网让 DNS 答案取决于查询看似来自哪里,于是每个地区被递给它最近的健康边缘的地址;anycast 和 CDN 在路由层依赖同样的把戏。来自不同探针的不同地址,是本地化正在做它的工作。它只有在一个地区的地址死了、而其他地址能用时才成为一个发现——那时这个名字在忠实地把那个地区的用户送往一个坏掉的边缘。