节点延迟测速怎么测准确?从客户端初筛到真实请求复核
简答:节点延迟测速不准,通常是测试目标、分流路径或采样次数不一致。关闭其他代理并固定网络后,先用客户端同一测试地址初筛,再用 curl 重复请求,最后用真实网页、下载或 API 验证。
定义:节点延迟是一次网络请求从发起到获得响应所经历的时间,但不同工具可能测量 ICMP、TCP、TLS 或 HTTP 响应中的不同阶段。
先试这一步:固定条件后再测 5 次
免责声明:测速结果只反映当前设备、网络、测试目标和时间段下的表现,不能直接代表节点长期速度或所有网站的访问体验。
如果你只在客户端里点一次“测速”,读到的通常只是某个健康检查地址的响应耗时。这个数字适合做初筛,不适合单独判断网页打开、视频播放或大文件下载体验。Mihomo 的代理组健康检查支持配置测试地址、超时时间和期望状态码;官方文档示例使用 https://www.gstatic.com/generate_204,并可将期望状态设为 204。可参考 Mihomo 代理组配置文档 和 Mihomo 代理集合健康检查文档。
- 固定一台设备和一条网络,测试期间不要切换 Wi-Fi、移动网络或网卡。
- 固定一个测试目标,例如
https://www.gstatic.com/generate_204,不要每次换地址。 - 固定一个节点,并确认客户端日志或连接面板显示的确实是该节点。
- 每个节点至少测 3 次,建议测 5 次;不要只记录最低值。
- 分别记录成功次数、失败次数、最小值、中位数和最大值,再做真实请求复核。
判断标准不是“数字越低越好”这么简单,而是比较同一条件下的稳定性:一个节点如果第一次很低、后面频繁超时,通常不如延迟略高但多次结果接近的节点。
先分清你测到的到底是什么
| 测试方式 | 主要测量内容 | 适合用途 | 不能直接说明 |
|---|---|---|---|
| ICMP Ping | 设备到目标 IP 的 ICMP 往返时间 | 观察基础网络延迟与 ICMP 丢包 | 不能代表代理后的网页响应 |
| TCP 连接 | 建立 TCP 连接所需时间 | 判断连接入口是否容易建立 | 不包含完整网页响应 |
| HTTP 响应 | 经节点访问指定 URL 的响应耗时 | 客户端初筛和节点横向比较 | 不等于下载速度 |
| TLS 握手 | HTTPS 连接完成 TLS 协商的时间 | 定位 HTTPS 握手慢的问题 | 对 HTTP 地址没有 TLS 阶段 |
| TTFB | 收到第一个响应字节前的时间 | 观察服务端处理与链路响应 | 不代表完整页面加载完成 |
| 总耗时与吞吐 | 请求完成时间和下载速率 | 验证下载、接口或网页体验 | 受文件大小、服务端和并发影响 |
curl 官方手册将 time_connect 定义为完成到远端主机或代理的 TCP 连接时间,将 time_appconnect 定义为完成 SSL、SSH 等握手的时间,将 time_starttransfer 定义为收到第一个字节前的时间,将 time_total 定义为整个操作的总时间。字段说明见 curl 官方手册。
因此,HTTP 测试地址返回 204 时,重点看响应是否成功、time_starttransfer 和 time_total。如果地址是 http:// 而不是 https://,time_appconnect 为 0 属于正常现象;对于很小的探测响应,speed_download 也没有足够代表性。
用客户端做初筛:避免被分流规则误导
客户端内建测速可以快速筛掉明显不可用的节点,但要先控制分流。若客户端处于规则模式,请确认测试地址没有命中 DIRECT 或其他策略组;否则你看到的可能是直连或另一条出站链路,而不是正在比较的节点。
- 暂时切换到全局模式,或在
select策略组中手动固定被测节点。 - 在客户端连接面板或日志中确认测试目标实际使用了该节点。
- 统一测试地址、超时时间和期望状态码;以客户端设置页和当前版本字段为准。
- 连续测试 3 至 5 次,记录每次结果和失败次数。
Mihomo 的代理组配置支持 url、timeout 和 expected-status 等字段;设置了期望状态码后,只有返回匹配状态的节点才会被视为可用。相关字段可核对 Mihomo 官方代理组文档。
如果你使用 Mihomo 内核,还可以通过外部控制器 API 对单个节点测试指定 URL。先在配置中确认 external-controller 和 secret,官方文档说明外部控制器用于通过 RESTful API 控制内核,默认示例监听 127.0.0.1:9090,详见 Mihomo 全局配置文档。
下面的示例假设控制器端口为 9090、API 密钥为 YOUR_SECRET,节点名称先替换成不含空格的 NODE_NAME。端口以客户端设置页为准。
curl.exe -sS -H "Authorization: Bearer YOUR_SECRET" "http://127.0.0.1:9090/proxies/NODE_NAME/delay?url=https://www.gstatic.com/generate_204&timeout=5000&expected=204"预期结果是返回包含 delay 的 JSON。Mihomo API 文档说明,/proxies/proxies_name/delay 用于测试指定代理,支持 url、timeout 和可选的 expected 参数。若返回错误,先检查节点名称、API 密钥、控制器端口和 URL 是否与当前内核配置一致。
用 curl 复核:Windows、macOS 和 Linux 的可复制方法
curl 可以显示名称解析、连接、TLS、首字节和总耗时。curl 官方教程说明可使用 -x 指定代理,并支持 HTTP、SOCKS 等代理类型;相关说明见 curl 官方教程。
先测直连基线:测试前退出代理客户端,或至少关闭 TUN 和系统代理。仅使用 --noproxy "*" 不足以保证是真正直连,因为 TUN 仍可能接管流量。还要检查 http_proxy、https_proxy、ALL_PROXY 等环境变量。
macOS 或 Linux 可先执行:
env | grep -i proxy
curl -sS --noproxy "*" -o /dev/null -w "code=%{http_code} dns=%{time_namelookup} connect=%{time_connect} tls=%{time_appconnect} ttfb=%{time_starttransfer} total=%{time_total}\n" "https://www.gstatic.com/generate_204"Windows PowerShell 5.x 中,curl 是 Invoke-WebRequest 的别名,参数并不等同于 curl;应明确调用 curl.exe。Microsoft 文档也说明了这一别名行为,见 Microsoft Learn:curl on Windows。
Windows PowerShell 可先查看代理环境变量:
Get-ChildItem Env: | Where-Object { $_.Name -match 'proxy' }关闭客户端 TUN、退出其他代理并确认环境变量没有残留后,执行 5 次直连基线:
1..5 | ForEach-Object { curl.exe -sS --noproxy "*" -o NUL -w "run=$_ code=%{http_code} dns=%{time_namelookup} connect=%{time_connect} tls=%{time_appconnect} ttfb=%{time_starttransfer} total=%{time_total}`n" "https://www.gstatic.com/generate_204" }再测经 HTTP 代理:把 7890 替换成客户端设置页显示的 HTTP 或混合端口。端口全文以客户端设置页为准。
1..5 | ForEach-Object { curl.exe -sS -x "http://127.0.0.1:7890" -o NUL -w "run=$_ code=%{http_code} connect=%{time_connect} tls=%{time_appconnect} ttfb=%{time_starttransfer} total=%{time_total}`n" "https://www.gstatic.com/generate_204" }经代理测试时,先把客户端切到全局模式,或手动固定被测节点,再通过连接面板确认实际出站节点。即使 curl 使用了本地混合端口,客户端仍可能按照分流规则把请求送到 DIRECT 或其他策略组。
对比时只改变一个变量:先比较同一目标的直连和代理,再比较不同节点;不要同时更换测试地址、网络、协议和客户端模式。若代理结果明显慢于直连,继续看是连接时间、TLS 时间、TTFB 还是总耗时增加,才能缩小问题范围。
丢包、抖动和真实体验:不要把一个指标当结论
HTTP 请求失败次数可以记录“请求成功率”,但不能直接称为 ICMP 丢包率。丢包应使用 Ping 或其他专门工具观察;HTTP 失败还可能由 DNS、TLS、目标站限制、代理规则或响应状态码造成。
Windows 可使用:
ping -n 20 目标域名或目标IPmacOS 或 Linux 可使用:
ping -c 20 目标域名或目标IP这里的 Ping 测的是设备到目标的 ICMP 路径,不一定经过代理节点,因此只能作为基础网络参考。若要判断代理链路,优先记录 curl 的 HTTP 成功次数、超时次数和响应时间;若需要进一步定位中间链路,再使用系统可用的路径诊断工具,并明确它测的是哪一段路径。
抖动可以用相邻样本差值做粗略观察。样本较少时,记录最小值、中位数和最大值即可;样本达到 20 次以上,再额外观察 P95 会更有参考价值。不要把没有统一测试条件的 P95、速度或丢包数字跨设备直接比较。
| 现象 | 优先检查 | 判定与下一步 |
|---|---|---|
| 延迟低但网页打不开 | HTTP 状态码、分流规则、TLS 和 DNS | 先看 curl 的 code、ttfb 和错误信息,不要只看毫秒数 |
| 延迟稳定但下载慢 | 固定大小文件、单连接吞吐和目标站限制 | 用相同文件和相同目标复测,避免用 204 探测地址判断带宽 |
| 第一次很快,后面超时 | 节点稳定性、测试间隔和高峰期链路 | 增加样本并记录失败次数,必要时换节点 |
| 客户端延迟很低,curl 很高 | 测试 URL、协议、分流和代理端口 | 确认两次测试经过同一节点、同一目标和同一出站模式 |
| 不同地区节点无法直接比较 | 目标位置和业务用途 | 优先比较同一地区或同一真实业务目标下的结果 |
最后必须做一次真实场景复核:打开你实际要用的网页,发起一次常用 API 请求,或下载一个固定大小的文件。探测地址只能说明该地址的响应情况,不能保证所有网站都同样快。
一张可复制的测速记录表
建议每个节点至少保留以下字段,并在白天和晚高峰分别测试。日期按实际记录填写,不要把不同日期的数据混在一起。
| 时间 | 节点 | 网络与设备 | 测试目标 | 次数 | 成功/失败 | 中位数 | 最大值 | 真实请求结果 |
|---|---|---|---|---|---|---|---|---|
| 填写实际时间 | 填写节点名称 | 固定设备与网络 | 固定 URL | 5 或更多 | 例如 5/0 | 填写实测值 | 填写实测值 | 网页、API 或下载结果 |
- 可用性:先看是否能连续完成请求,再看延迟。
- 稳定性:比较中位数和最大值,观察是否存在偶发超时。
- 链路定位:对比
connect、tls、ttfb和total,不要把所有慢都归因于节点。 - 业务验证:用实际目标复测,固定文件大小、网页或 API,避免测试内容变化造成误判。
- 时间因素:至少在两个时段复测;如果高峰期明显变差,应记录时段后再决定是否更换节点。
如果你的目标只是筛选“能不能用”,客户端健康检查足够;如果目标是判断网页、下载或接口体验,就必须加入 curl 复核和真实请求。最准确的结果不是某次最低延迟,而是在相同条件下重复后仍然稳定的结果。
常见问题
节点延迟越低就一定越快吗?
不一定。延迟通常只代表某个测试地址的响应时间,下载速度还受带宽、目标站、拥塞、并发和服务端处理影响。应先看连续请求是否稳定,再用真实网页、API 或固定文件复测。
为什么客户端显示 50 ms,实际打开网页却很慢?
客户端可能只测了轻量探测地址,网页请求还要经过 DNS、TCP、TLS、规则匹配、服务端处理和页面资源加载。请用 curl 看 TTFB 与总耗时,并确认测试请求没有被分流到 DIRECT 或其他策略组。
测速时要不要关闭 TUN 模式?
测直连基线时应关闭 TUN 或退出客户端,否则流量仍可能被 TUN 接管;仅设置 curl 的 --noproxy "*" 不足以证明是真直连。测代理链路时可以使用本地代理端口,但要固定全局模式或手动固定被测节点。
HTTP 失败次数能不能当作丢包率?
不能直接等同。HTTP 失败可能由超时、DNS、TLS、分流、目标站状态码或代理错误造成。丢包应使用 Ping 等工具观察;同时记录 HTTP 成功率,分别描述两类结果。
测试地址返回的不是 204,还能用来测速吗?
可以先看实际状态码,但要确认目标是否适合你的测试目的。若客户端配置了 expected-status,只有匹配的状态才会被视为可用;可以换用稳定的轻量探测地址,并用多个目标交叉复核,避免单个地址不可达、缓存或响应异常造成误判。
相关阅读
参考资料
- Mihomo 官方文档:代理组配置、测试地址、超时与 expected-status
- Mihomo 官方文档:代理集合健康检查
- Mihomo 官方文档:外部控制器 API 与代理延迟测试
- Mihomo 官方文档:external-controller 与 secret
- curl 官方手册:代理参数与时间统计字段(curl.se)
- curl 官方教程:代理、环境变量与请求用法(curl.se)
- Microsoft Learn:Windows 中的 curl 与 PowerShell 别名