凌晨 3:47,客户群里第三次 @ 我。这次的故障,用 ping 完全看不出来。
起点:一封"网络很慢"的工单
故事开始于一个再普通不过的周三凌晨。
我们有一个部署在新加坡的服务,给国内客户提供 API 调用。当晚客服小姐姐转过来一个 P1 工单,描述很简单:
"调用超时,但是我能 ping 通你们的服务器,延迟也才 80ms。这是不是你们的问题?"
按照我们的常规剧本,遇到这种情况第一反应是甩锅——ping 通且延迟正常,那大概率是客户那边代码或本地网络的问题。但工单里截图来了:
$ ping api.example.com
PING api.example.com (xxx.xxx.xxx.xxx): 56 data bytes
64 bytes from xxx.xxx.xxx.xxx: icmp_seq=0 ttl=49 time=72.341 ms
64 bytes from xxx.xxx.xxx.xxx: icmp_seq=1 ttl=49 time=71.892 ms
64 bytes from xxx.xxx.xxx.xxx: icmp_seq=2 ttl=49 time=72.105 ms
64 bytes from xxx.xxx.xxx.xxx: icmp_seq=3 ttl=49 time=71.998 ms
--- api.example.com ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 71.892/72.084/72.341/0.166 ms
漂亮的 ping 结果。0% 丢包,72ms 延迟稳定到小数点后第二位。这看起来比我家公司内网都健康。
但客户随后又发了一张图——他们的应用日志里,过去 30 分钟有 60% 的请求 connection timed out。
这两个信息凑在一起,整个事情就开始变得有意思了。
第一刀:ping 看到的 ≠ 业务看到的
很多人下意识把"ping 通"等同于"网络正常",这是排查里最常见也最致命的误区。
ping 用的是 ICMP 协议,本质上只是发个回声请求看对端 IP 是否存活。它不走 TCP,不经过应用层端口,更不会触碰你的负载均衡、防火墙策略、连接数限制。换句话说:
| 测试维度 | ping 能验证 | ping 不能验证 |
|---|---|---|
| IP 是否可达 | ✅ | |
| 端到端延迟 | ✅(ICMP 路径) | |
| 目标端口是否开放 | ❌ | |
| 防火墙是否拒绝 TCP | ❌ | |
| 服务进程是否健康 | ❌ | |
| TLS / HTTP 是否正常 | ❌ |
很多企业的边界设备甚至会优先放行 ICMP(避免被监控误报"机器掉线"),但同时对 TCP 流量做严格限制。在这种网络下,ping 永远漂亮,业务永远报错。
所以收到截图的第一秒,我就知道这次甩不了锅。
第二刀:换 tcping,真相浮出水面
让客户在他那边对我们的 443 端口做 tcping:
$ tcping api.example.com 443
Probing xxx.xxx.xxx.xxx:443/tcp - No data : seq=0 (failed)
Probing xxx.xxx.xxx.xxx:443/tcp - No data : seq=1 (failed)
Probing xxx.xxx.xxx.xxx:443/tcp - Port is open - time=158.421ms
Probing xxx.xxx.xxx.xxx:443/tcp - No data : seq=3 (failed)
Probing xxx.xxx.xxx.xxx:443/tcp - No data : seq=4 (failed)
Probing xxx.xxx.xxx.xxx:443/tcp - Port is open - time=312.998ms
Probing xxx.xxx.xxx.xxx:443/tcp - No data : seq=6 (failed)
来了。TCP 层 70% 失败,偶尔成功的也延迟翻倍——同一时刻 ICMP 层却 0% 丢包。
到这里基本能下一个判断:丢包不是发生在我们机房的接入层,也不是客户端本地——一定是中间某一跳路由器对 TCP 流量做了选择性丢弃,但对 ICMP 放行。
很多 ISP 的跨境节点在拥塞时会优先丢 TCP(特别是大包),ICMP 包小且不携带载荷,反而能"幸存"。这就是为什么 ping 漂亮但 tcping 全军覆没。
⚡️ 顺手记一个反直觉的事实:你 tcping 看到的延迟可能比 ping 高一截。原因是 ICMP 是单包来回,而 TCP 三次握手要经过排队、重传可能性更大,且部分网络设备给 TCP 的处理优先级低于 ICMP。所以同一目标,tcping > ping 是常态,反过来才奇怪。
第三刀:mtr 定位到具体哪一跳坏了
知道是中间路由的问题不算结案,得找出具体是哪一跳。这时候 traceroute / mtr 上场。
mtr 比 traceroute 强的地方在于它持续发包统计每一跳的丢包率,而不是只跑一次:
Packets Pings
Host Loss% Snt Last Avg Best Wrst StDev
1. 192.168.1.1 0.0% 100 0.4 0.5 0.3 1.2 0.1
2. 10.32.0.1 0.0% 100 3.2 3.4 2.9 8.1 0.6
3. 218.xx.xx.1 0.0% 100 8.7 9.1 8.2 15.4 1.0
4. 202.xx.xx.85 0.0% 100 12.3 12.8 11.9 18.6 0.8
5. 219.xx.xx.149 0.0% 100 45.2 46.1 44.8 52.1 1.2
6. 202.xx.xx.34 67.0% 100 71.5 78.2 68.9 145.3 18.4 ← 这里
7. 203.xx.xx.18 65.0% 100 72.8 79.1 69.2 152.7 19.1
8. 103.xx.xx.142 65.0% 100 73.2 80.0 70.1 158.4 20.2
9. xxx.xxx.xxx.xxx 66.0% 100 72.6 79.5 69.8 155.2 19.6
第 6 跳开始出现 65%+ 的丢包,且后续每一跳的丢包率都跟着传播——这是教科书式的单点拥塞。
⚡️ 看 mtr 输出的小窍门:只有第一跳出现高丢包而后续跳没有传染,往往是那一跳路由器对 ICMP 限速(不是真丢),可以忽略。从某一跳开始所有后续都丢,那才是真问题。
第四刀:从一个节点测,永远只是一面之词
这一步是我那晚最大的认知刷新。
我让客户从他自己机器跑出来上面的 mtr 之后,本来想直接拿这个证据去找上游 ISP。但我们 SRE Leader 拍我一下:"你确定这是公网问题,不是客户那条出口的问题?"
是啊。单点测试有个根本缺陷:你看到的拥塞,可能只属于你这条 ISP 路径。 同一时刻从不同地区、不同运营商访问,可能完全没事。
所以我让客户的同事在另外几个城市的机器上同步跑 tcping 和 mtr。结果是:
- 北京电信 → 新加坡:丢包严重,定位到香港某中转节点
- 北京联通 → 新加坡:完全正常
- 上海移动 → 新加坡:丢包,但定位到不同的中转节点
- 广州电信 → 新加坡:完全正常
到这一步证据链就完整了:问题确实在公网,且是电信跨境出口拥塞。但只看客户那一台机器,根本不可能得出这个结论。
那晚我手动协调了 4 台机器在不同地区同步跑测试,光是同步操作就花了快 2 小时。后来我意识到这种"多节点同步对比"其实就是典型的网络诊断刚需,市面上有不少现成的多节点测试平台可以一键搞定,比手动开 4 个 SSH 高效太多。我现在团队里这种活基本都丢给在线工具跑——拿个图就走,比手动方便一万倍。
复盘:可复用的 4 步排查方法论
凌晨 5 点多事情解决(ISP 给我们换了一条 BGP 路径),那晚熬出来的方法论我后来整理成一个 SOP,团队新人遇到类似问题照着跑就行:
第 1 步 · ping 验存活,但不下结论 ping 通只代表 IP 存活,不代表服务可用。无论 ping 结果多漂亮,绝对不要跳过下一步。
第 2 步 · tcping 验业务端口 直接打你的业务端口(80 / 443 / 3306 / 自定义端口),如果 tcping 失败而 ping 成功,几乎可以锁定中间路由对 TCP 流量异常。这一步是排查的核心节点。
第 3 步 · mtr 定位异常跳 持续发包至少 100 次(mtr 默认 10 次太少容易误判)。看从哪一跳开始连续丢包,那就是事故现场。
第 4 步 · 多节点对比定锅 单点测试只能描述现象,不能定位根因。同时在 3 个以上不同地区/运营商的节点跑测试,对比结果,才能区分是"公网问题""客户出口问题""目标机房问题"还是"特定 ISP 跨境路径问题"。
一些后续的思考
这次事故让我系统性地把网络诊断工具梳理了一遍,几个心得分享:
ICMP 不等于业务,永远以业务协议(TCP / HTTP)为准做最终判断。监控告警里如果只挂了 ping 探测,是非常脆弱的。
单点视角是排查的最大陷阱。最少要从 3 个不同 ASN 的节点对比看,不然永远在猜。多节点测试这事手动做太累,建议直接用现成工具,比如我现在常用的 BiuPing,全国节点 + 多运营商 + IPv4/IPv6 双栈都打通了,ping、tcping、mtr、网站测速一个站搞定,跨国排查特别顺手。
给监控加上 tcping 探针。光监控 ping 在 90% 的故障里都会失效——你的服务挂了,但你的 ICMP 还在欢快地回应。这种监控不如不要。
保存历史基线。同一个目标在正常时候的 mtr 路径长什么样、每一跳延迟大概多少,平时多看几眼,出问题时一眼就能看出"这条路径不对劲"。
工具是死的,方法论是活的。下次再遇到"ping 得通但访问不了"的工单,别下意识甩锅,先按这四步走一遍——大概率你会比客户更早发现真凶。