jmeter直连mysql压测无参考价值,因绕过hyperf完整请求生命周期(路由、中间件、协程上下文、连接池复用、orm逻辑),实测的是裸连接能力而非业务接口性能。

压测结果远低于预期,不是 Swoole 版本或 CPU 核数的问题,而是某处没切到协程的 sleep()、一个没配连接池的 Redis 实例、或者 max_coroutine 被设成默认 100000 却没结合 worker_num 动态调整——这些细节不拉出来对齐,压测数据就是幻觉。
为什么 JMeter 直连 MySQL 压出来的 QPS 毫无参考价值
直连绕过了 Hyperf 整个请求生命周期:路由匹配、中间件执行、协程上下文注入、DB 连接池复用、ORM 封装逻辑全被跳过。你测的不是业务接口,是裸连接能力。
-
Communications link failure在直连时高频报错,但/api/user/{id}完全正常 → 实际是连接池超时或max_connections配置不一致 - 直连压出 8000 QPS,真实接口仅 1200 QPS,CPU/内存平稳 → 大概率触发
max_coroutine排队,或worker_num设置过低 - P95 响应时间陡升但错误率为 0 → 协程资源耗尽,新请求在等待可用协程,不是 DB 慢也不是网络卡
JMeter 命令行压测必须加的三个硬性配置
GUI 模式会因 Swing 线程和 JVM GC 反向拖慢结果,必须用命令行非 GUI 模式。
- 启动命令固定为:
jmeter -n -t test.jmx -l result.jtl -e -o report/ - 提前修改
jmeter.bat或jmeter.sh中的HEAP="-Xms2g -Xmx2g",否则高并发下 GC 会污染 RT 数据 - 线程组必须用「Concurrency Thread Group」插件(非原生线程组),Ramp-Up Period 别设为 0;日常模拟建议 300 秒,给系统缓冲时间
hyperf/metric 指标必须和 JMeter 结果交叉验证
只看 JMeter 的 Aggregate Report 是盲人摸象。Hyperf 运行时指标才是瓶颈定位依据。
- 启用
hyperf/metric并设'use_standalone_process' => true,避免监控逻辑干扰业务协程 - 重点关注
coroutine.active是否持续逼近max_coroutine,逼近即表示协程资源吃紧 - 对比
db.pool.waiting和redis.pool.waiting,若长期 > 0,说明连接池容量不足或下游响应变慢 -
http.server.request.duration的 P99 值若远高于 JMeter 报告值,说明框架层有未捕获的阻塞点(比如漏掉协程化改造的file_get_contents)
连接池参数怎么设才不翻车
min_connections 和 max_connections 设错会导致连接耗尽或资源浪费,不是越大胆越好。
-
min_connections不建议设为 0 —— 即使没请求,也至少保留 1~2 个空闲连接,避免首请求触发建连延迟 -
max_connections要结合 DB 实例最大连接数(如 MySQL 的max_connections)来定,通常按worker_num × 每进程并发请求数 × 1.2估算,再留 20% 余量;例如 8 个 Worker,每个处理 50 并发,建议设为 480~600 - 若设得过高(比如 >1000),而 MySQL 实例只允许 500 连接,会触发
Too many connections错误,且错误日志中不会直接提示是连接池超限,而是表现为随机连接失败
真正卡住万级 QPS 的,往往不是 Swoole 版本或 CPU 核数,而是某个没显式暴露的阻塞点:比如一个没加 @Async 的日志写入、一段没封装进协程的 curl_exec、或者 Coroutine::set(['hook_flags' => SWOOLE_HOOK_ALL]) 没生效导致 socket 调用未被劫持——这些地方不逐项排查,优化就只是调参游戏。











