type
Post
status
Published
date
Apr 9, 2026
slug
gateway005
summary
tags
gateway
推荐
category
icon
password
说明
这次压测的目的是,把正常情况下这个网关不同路径的性能基线测清楚。后面阶段在 fallback、unhealthy backend、readyz 波动等故障场景下,性能代价才有可对照的基线。
一、问题定义
压测网关最容易犯的错误是:没分清楚不同层次的开销
压测一个网关时,必须先分清楚自己测到的是网关内部路径,还是网关加 adapter 的整条本地路径。只有先把层次分开,后面的性能数字才有解释力。
在这个项目里,至少有两条不同的测量路径:
- in-process mock path:主要测网关内部路径
- local HTTP adapter path:测网关内部路径 + 真实 HTTP adapter 开销
在当前仓库里:
- mock path 主要覆盖:
auth、governance、routing、JSON shaping
- HTTP adapter path 额外覆盖:
socket I/O、HTTP request construction、response parsing、JSON encode / decode(请求构造、socket I/O、响应解析与 JSON 编解码)
二、测量对象分层图
先把测量对象说清楚。

这张图要表达的是:
- mock path 更接近测 gateway internal path
- adapter path 更接近测 gateway + adapter 的本地真实代码路径
两条路径要区分清楚。
三、压测工具边界
我做了一个面向本网关项目验证的轻量压测工具
cmd/loadtest,目的是为了稳定复现 non-stream / stream 两条路径,并把网关内部路径和 adapter 路径分层测清楚它具备的能力包括:
- 压
POST /v1/chat/completions
- 支持 non-stream 和 stream
- 输出 success / failure
- 输出 latency P50 / P95 / max
- stream 模式额外输出 TTFT 和 chunk 总数
这是当前阶段足够实用的 benchmark driver。
四、non-stream benchmark
运行参数:
- requests =
100
- concurrency =
10
结果如下:
路径 | Success | Failure | Approx QPS | P50 | P95 | Max |
In-process mock | 100 | 0 | 740.7 req/s | 11 ms | 22 ms | 24 ms |
Local HTTP adapter | 100 | 0 | 609.8 req/s | 14 ms | 34 ms | 37 ms |
这组结果说明:
HTTP adapter path 引入了真实请求构造和响应解析成本,即使上游仍然是本地的。
这组数字展示了:
- 网关内部路径本身的开销
- 进入真实 adapter 代码路径后,多付出了多少本地成本
non-stream 结果图
这张图想说明的是:
- mock path 的结果更接近 gateway internal path
- adapter path 的额外代价主要来自 HTTP adapter 路径,而不是网关内部逻辑突然变差
五、stream benchmark
运行参数:
- requests =
50
- concurrency =
5
结果如下:
路径 | Success | Failure | Throughput | Latency P95 | TTFT P95 | Chunks |
In-process mock | 50 | 0 | 549.5 req/s | 19 ms | 12 ms | 200 |
Local HTTP adapter | 50 | 0 | 61.4 req/s | 98 ms | 28 ms | 150 |
这里最关键的不是整体变慢,而是:
TTFT 仍然相对低,总流式时延的大头发生在首 chunk 之后。
原因很清楚:当前 synthetic upstream 会通过多次写出,把整条流式过程刻意拉长。
因此,对流式系统来说,至少要区分两个问题:
- TTFT:用户第一次看到内容要多久
- time to full completion:整条流什么时候结束
这两个指标不能混在一起理解。
stream 结果图:TTFT vs 总时延
这张图要表达的是:
adapter path 的主要增量不在“首 token 出来之前”,而在“首 token 之后整条流被拉长”。
也就是说,对流式系统来说,“首包快”和“整条流结束快”不是同一个命题。
六、为什么压测前必须调整 tenant 限额
本地 seed tenant 默认是:
60 req/min
这个值适合 smoke test,不适合 benchmark。
方法说明
这次 benchmark 前临时调高 tenant 限额,不是为了“跑得更好看”,而是为了隔离治理层对结果的干扰。
如果限流器先把压测挡下来,那么测出来的就是 quota 策略,而不是 gateway path 本身。
原因很简单:
如果你明明在测网关路径,却让 rate limiter 先把压测挡下来,那么你测到的就是治理策略,而不是网关性能。
所以 benchmark 前会临时调高 tenant 限额,结束后再恢复。
这是在保证:
当前 benchmark 测的是 gateway layer,而不是 rate limiter。
七、资源快照:本地依赖成本主要落在 MySQL
100 请求那组 benchmark 结束得太快,一次性的进程采样意义不大。
因此我又补了一次更长的观测:
观测期间的资源快照显示:
Component | Approx Memory |
Gateway | 28 MiB |
MySQL | 587.8 MiB |
Redis | 9.953 MiB |
这组快照说明了一件事:
当前本地 benchmark 环境里的资源 footprint 主导项是 MySQL,而不是 Redis。
也就是说,在当前本地验证环境里,状态存储层的资源体量明显高于缓存层。
八、边界说明
本文里的 adapter path 对比,不是 hosted provider benchmark。
当前使用的是本地 synthetic OpenAI-compatible upstream,因此测到的是:
网关路径、adapter 路径、本地 upstream 交互开销
它没有覆盖:
- WAN 抖动、真实 provider 侧波动、公网环境下的复杂时延分布
所以这组 benchmark 的正确定位是:
它表示网关自身开销,但它不能替代真实 hosted-provider latency study。
九、如何复现实验
复现实验说明这组 benchmark 的价值也在于它可以被稳定复现。当前复现实验分两条路径:
- in-process mock path:更接近测 gateway internal path
- local HTTP adapter path:更接近测 gateway + adapter 的本地真实代码路径
十、结论
LLM Access Gateway正常基线已经建立。
non-stream 的 in-process mock path 为740.7 req/sP95 22 mslocal HTTP adapter path 为609.8 req/sP95 34 ms在 stream 场景下,adapter path 的TTFT P95为28 ms,但总Latency P95上升到98 ms
分享
