自建 AI 中转带宽实测方法 (Bandwidth Benchmarking for Self-Hosted AI Relay)
目标
给一台跑 API 中转(new-api / CLIProxyAPI 之类)的 VPS 测出:真实出入口带宽、
多连接聚合能力、以及"瓶颈到底在客户端链路、边缘 (edge)、还是容器本身"。
前置
- 站点 nginx 可改(临时加 location,测完必须删)
- 本机测自己服务器时必须清空代理变量,否则测的是代理链路:
$env:HTTP_PROXY="";$env:HTTPS_PROXY="";$env:ALL_PROXY="";$env:NO_PROXY="*"
步骤
- 临时测速端点(加在每个 server 块里,容易只加一份导致 https 端口没生效):
location = /__sink {
client_max_body_size 0;
proxy_request_buffering on;
proxy_pass http://127.0.0.1:9; # 故意指向关闭端口,只为强制读完 body
}
location ^~ /__speed/ {
root /tmp; # 放 /tmp/__speed/down5.bin
access_log off;
}nginx -t && nginx -s reload。- 下行:
curl -o NUL -w "%{speed_download} %{time_total}" https://域名/__speed/down5.bin,
单流 3–4 次取稳定值,再跑 4 并发 / 8 并发看聚合。 - 上行:
curl --data-binary @20MB文件 https://域名/__sink。 三段隔离(关键,决定优化方向):
- 容器自身出口:在容器里直连公网测速源,量商品标称带宽是否属实。
- 回环:在容器里访问自己的公网域名(容器→边缘→容器),量边缘回源段能力。
- 容器→目标地区:在容器里直连目标地区镜像站,量与客户端看到的数是否同一量级。
- 收尾:删 location、
nginx -t && nginx -s reload、删临时文件,
再打一次站点根路径与一条真实 API 请求确认没改坏。
验证
- 三段数字若"客户端经边缘"≈"容器直连目标地区",则瓶颈在跨地区链路,边缘无责。
- 若回环能跑满容器出口带宽,则边缘与回源段无责。
常见失败点
- 用
return 204/return 200做上行测速端点会严重低估:nginx 不读完 body 就应答,
实测 487 KB/s,改成强制读 body 后同链路 3.06 MB/s(低估 6 倍)。SFTP 直传可交叉验证。 - 只在一个 server 块加 location,80/443 表现不一致。
- 没清代理变量,测出来的是代理出口的带宽。
- 边缘 WAF 会对 POST body 做内容特征拦截:
<script>alert(1)</script>、1 UNION SELECT ...这类 3–5 KB 小 body 直接 403,而 1.15 MB 纯二进制照过。
即拦截看的是内容签名不是体积。真实开发类 prompt 带<script>或 SQL 会被拦。
判断方法:拿同样的 body 打自己的测速端点,403=WAF、502=已到 nginx。
适用边界
- 只适用于自有域名 + 自有 nginx 的直连测试;跑在第三方 CDN/WAF 后面时,
测到的是"到边缘"而不是"到源站"。 - 压测目标是自己服务器;不要拿真实上游 API 打垃圾 payload 做压测。
参考量级(LA 容器,标称 50M;中国大陆客户端)
| 项 | 数值 |
|---|---|
| 容器→就近公网单流 | 6.0–6.4 MB/s(标称属实) |
| 客户端经边缘下行单流 | 2.2 MB/s(上海方向 2.56 MB/s) |
| 客户端经边缘下行 4 / 8 并发 | 3.84 / 5.34 MB/s(逼近 50M 上限) |
| 客户端上行单流 | 3.06 MB/s |
| 容器直连中国大陆单流 | 1.96 MB/s(与上面 2.2 同量级→瓶颈是跨太平洋链路) |
| 纯文本流式聊天单流占用 | 5–15 KB/s,带宽不是并发瓶颈,上游账号数才是 |
三段延迟法:先判断「该换协议」还是「该换线路」
带宽测完还要测延迟。换 UDP 协议(Hysteria2 / TUIC)的动机是丢包,不是延迟——这两个数必须分开量,否则会花一整晚换协议而问题原地不动。
三段实测(2026-09-21 22:40 前后,宁波电信 → LA 容器):
| 段 | 命令 | 结果 |
|---|---|---|
| 客户端 → 容器 | ping -n 30 <ip>;ping -n 20 -l 1400 <ip> | 小包 0% 丢;1400 字节大包丢 5%;RTT 154–233 ms,均值 ~182 ms |
| 容器 → 目标服务 | 容器内 ping <api 域名> / curl -w | 0.99 ms;TLS 握手 22 ms,TTFB 58 ms |
| 客户端 → 目标服务 | 客户端经容器(ssh -D 建隧道后 curl)vs 经本地商业节点 curl | 经容器 720–880 ms;经商业节点 360–540 ms |
判读要点:
- 容器→目标 0.99 ms,直接否掉「上游风控机房 IP / 被封限速」这类说法。目标服务就在隔壁机房,容器出去几乎零成本。
- ICMP 大包丢包率 ≠ 真丢包率。判据要用同机 TCP 计数器:
nstat -az | grep -E "TcpOutSegs|TcpRetransSegs"。本期 816/582841 ≈ 0.14%;而按 0.14% 代入 Mathis 公式,180 ms RTT 下单流上限只有 ~2 Mbps,实测却是 20 Mbps——反证真实丢包远低于 ICMP 显示值,那 5% 是 ICMP 被限速。 - 延迟三段法比带宽法更快定性:RTT 几乎全在「客户端→容器」这一段。
结论对照:
| 瓶颈形态 | 该动什么 |
|---|---|
| 真丢包(TCP 重传率 ≳ 1%) | 换 UDP 协议有意义——Brutal 拥塞控制把丢包当噪音直接无视 |
| 只有 RTT 高、丢包 ≈ 0 | 换协议没用。CUBIC 没被冤枉,Hysteria2 一分钱买不到,还赌上运营商晚高峰 UDP QoS 的风险 |
| 目标是「往返次数多」的交互式 API(gRPC / Antigravity / Gemini CLI) | 换线路(CN2 GIA / 国内中转),或把调用挪到容器本地跑(容器→目标 1 ms),而不是让每次 gRPC 往返都跨一次太平洋 |
实测支撑:同一目标,经容器 720–880 ms,经本地商业节点 360–540 ms——快一倍。所以「Google 流量走哪个节点」是比「用什么协议」重要得多的问题。
换协议前必读:NAT VPS 不转发 UDP 导致 QUIC 类协议全废 (NAT VPS Without UDP Forwarding Blocks QUIC Protocols) —— 共享 IP 小鸡可能压根收不到 UDP,协议选型在买机器时就定了。
本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/Network