平台工程

ping 通不等于路通 · fake-ip 假信号与节点带宽实测选型

入档:2026-07-27 来源:一次「能 ping 通 coursera.org,但浏览器看课程极卡」的排障会话;本机 Windows 10 Pro + Clash Verge Rev(verge-mihomo v1.19.21,rule 模式,TUN 关闭,系统代理 127.0.0.1:7897) 状态:已定位并修复,运行态 + 配置文件双写落地;insight 3 是 全站文字截断体检_检测工具本身要先被证伪_v1跨项目二次验证(那篇标注「尚未跨项目二次验证」,本次补上)

事实记录(不可修改区)

症状与首轮诊断

先排除的两个常见怀疑(都不成立)

节点评测

40 个节点,内置延迟测试 34 个可用。对延迟前 14 名逐个切换 + 实测带宽(speed.cloudflare.com,50 MB 上限、15 秒窗口):

排名带宽延迟节点
1133.33 Mbps72ms🇯🇵 日本03【1.0】
2133.33 Mbps92ms🇸🇬 新加坡01【1.0】
3100 Mbps36ms🇭🇰 香港03【1.0】
450 Mbps126ms🇮🇳 印度01【1.0】
540 Mbps123ms🇰🇷 韩国01【1.0】
135.07 Mbps91ms🇯🇵 日本10【0.5】
142.72 Mbps113ms🇯🇵 日本01【2.0】← 原用节点

对前 3 名用 Coursera 真实链路复测,香港03 全面最优(coursera.org TLS 0.203s、视频 CDN TLS 0.203s / TTFB 0.282s、api 0.843s)。定香港03。

修复前后

日本01(原)香港03(现)
持续带宽2.72 Mbps100–133 Mbps
coursera.org TLS6.36s0.19–0.25s
视频 CDN TTFB2.38s0.27s
流量倍率2.01.0

Coursera 720p 约需 3 Mbps —— 原节点 2.72 Mbps 连 480p 都紧张,且播放器每取一个分片都要重新握手,每次干等 6 秒。

三个把我带偏的工具故障

  1. 测速全 0:首轮 14 个节点全部返回 0 Mbps,形似「所有节点都挂了」。实为探针请求 bytes=209715200 超出 Cloudflare 单请求上限,返回 403 + size=1。改回 50 MB 后立刻测出 17.5 MB/s。
  2. 切换静默失效bench.ps1$GROUP = '国外默认',PowerShell 5.1 按 ANSI 读 UTF-8 无 BOM 的 .ps1,中文变成乱码,Set-MihomoProxy 切的是不存在的组。不报错,只是 original node: 打印为空。转成 UTF-8 with BOM 后正常。
  3. chunked 解码越界:mihomo /proxies 走 chunked,chunk 长度是字节数,我在已 UTF-8 解码的字符串上按该长度 Substring,中文 1 字符 = 3 字节,直接抛 ArgumentOutOfRangeException。改成字节级去帧、最后统一解码。

落地

一句话总结

ping 通证明不了链路可用——在 fake-ip 模式下它连出网都没发生;而选节点也不能看延迟,Clash 内置延迟测试只测握手,本次带宽垫底(2.72 Mbps)的那个节点,延迟排第 8、看起来完全正常。

五条可复用 insight

1. fake-ip 模式下的 ping 是自问自答 ⚠️首次

enhanced-mode: fake-ip 时,代理给每个域名发一个 198.18.0.0/16 段的本地虚拟地址,ICMP 由本机应答。所以:

ping 通在这里不是「网络通」的证据,而是「代理接管了 DNS」的证据。 用户拿它当健康信号,恰恰因为它永远是绿的。

判据:诊断信号必须打在真实链路上。 本次有效的信号是 curl -wtime_appconnect(TLS 握手,含代理 CONNECT 隧道 + 远端握手)和 speed_download。看到 198.18.x.x 就该知道 ping / tracert / nslookup 这一层全部失去意义。

已有的 ChatGPT_Windows桌面版安装排障与账号合规边界_v1 提过「fake-ip 会让 DNS 返回保留网段,这是内部映射不等于 DNS 泄露」——本篇是同一现象的另一面:它同时让所有基于 IP 的连通性测试失效

2. 延迟不等于带宽,内置延迟测试选不出能看视频的节点 ⚠️首次

Clash 的「延迟测试」测的是一次 generate_204 的握手往返,不测吞吐。本次两者几乎不相关:

节点延迟排名带宽排名
日本018 / 3414 / 14(垫底)
日本105 / 3413 / 14
印度0110 / 344 / 14
香港031 / 343 / 14

一个 113ms 的节点可以只有 2.72 Mbps。 如果按 Clash 面板的绿色数字选节点,日本01 排在中上游,永远不会被怀疑。

判据:流媒体 / 大文件场景必须实测吞吐;延迟只用来做第一轮淘汰(筛掉超时的),不用来排序。

3. 探针返回「全 0」时,先怀疑探针 ⭐ 跨项目二次验证

首轮 14 个节点全返回 0 Mbps。这个结果看起来是一个结论(「机场整个废了」),实际是探针自己坏了——请求 200 MB 被 Cloudflare 拒绝,403。

这正是 全站文字截断体检_检测工具本身要先被证伪_v1 那条律的第二次现形,且是跨项目的(上次是浏览器 UI 体检脚本,这次是网络测速脚本):

两次的共同结构是:工具的输出形态很像事实(一张带数字的清单 / 一列整齐的 0),掩盖了「它根本没测成」。

具体判据(本次新增的操作层):0 是一个危险的返回值,因为它同时可能表示「测到了,就是 0」和「压根没测」。 探针必须把区分二者的字段一起打出来——本次是 %{http_code}%{size_download}code=403 size=1 一眼就和 code=200 size=52428800 分开了。我是在把这两个字段加进 -w 之后,1 次调用就定位的。

推论:任何返回「全部为 0 / 全部失败 / 全部相同」的批量结果,先跑一个已知good的样本自证,再信它。 全体一致的异常,通常是共因,而共因往往就在探针里。

4. 运行态改了 ≠ 配置落盘 ⚠️首次

通过 mihomo API PUT /proxies/{group} 切换节点,立即生效但不落盘。Clash Verge 把选择记在自己的 profiles.yamlselected 字段里,外部改动它不知道,重启后按文件恢复。

我是因为顺手核对了一遍 profiles.yaml,才发现它还写着日本01。如果只验证「现在快不快」,这次修复的寿命就是到下次重启为止——而用户不会把重启和变卡联系起来,只会觉得「上次修好了,又坏了」。

判据:凡是「运行时状态」和「配置文件」两处都存着的设置,改完必须两处都看。 验证问句不是「现在生效了吗」,而是「重启后还在吗」。

(同族:赛事状态机到点不切换_写入方不等于推进方_v1 的「有人写、有人显示,没人推进」——这里是「改了运行态、没人负责写回」。)

5. 非 ASCII 标识符遇上编码不匹配 = 静默走错分支 ⚠️首次

PowerShell 5.1 读 .ps1 默认按系统 ANSI 码页,而绝大多数工具写出的是 UTF-8 无 BOM。后果不是报错,是中文字符串静默变成乱码:

$GROUP = '国外默认'          # 文件里是 UTF-8,PS 5.1 读成乱码
Set-MihomoProxy -Group $GROUP -Name $node   # 切一个不存在的组,API 静默接受

于是脚本一路跑完,14 行结果整整齐齐,每一行都是错的

三条处置:

顺手教训

下次改进

关联文档

类型/平台工程主题/网络排障主题/代理链路