MySQL协程性能测试需分三层:协程调度、连接池行为、MySQL响应;须用co-phpunit在真实协程环境压测,监控连接复用、排队超时、空闲回收,并手动打点分析各阶段耗时,结合mysqld_exporter定位底层瓶颈。

直接测 MySQL 协程性能,不能只看“查询快不快”,得拆开看三层:协程调度层、连接池行为、MySQL 实际响应。Hyperf 的协程 MySQL 客户端本质是封装 Swoole\Coroutine\MySQL 或通过 Runtime::enableCoroutine + PDO 实现,所以测试必须覆盖真实协程上下文,避开 FPM 模式干扰。
测协程连接池吞吐与稳定性
重点验证连接复用、排队、超时是否按预期工作。
- 用
hyperf/testing启动协程测试环境(不是普通 PHPUnit),确保co-phpunit执行 - 写一个并发压测用例:启动 100 个协程,每个循环执行 50 次
SELECT 1,记录总耗时、失败数、最大等待延迟 - 关键观察点:
-
wait_timeout配置是否生效(比如设为 0.5s,看是否有协程因拿不到连接而抛ConnectionPoolTimeoutException) -
max_connections=10时,并发 50 协程下平均排队时间是否明显上升(可通过日志或自定义 Pool 监控埋点捕获) - 连接空闲回收是否及时(
max_idle_time=30,30 秒无使用应自动关闭)
-
测单次查询在协程中的真实耗时分布
hyperf_db_query_duration_ms 只统计 PDO 执行阶段,掩盖了连接获取、网络往返、锁等待等环节。
- 在测试中手动打点:
$start = microtime(true); $conn = $pool->get(); // 记录获取连接耗时 $stmt = $conn->prepare($sql); // 记录 prepare 耗时 $stmt->execute(); // 记录 execute 耗时(含网络+MySQL 处理) $end = microtime(true);
- 对比不同场景:
- 热连接(刚用完立刻再取)vs 冷连接(空闲 25 秒后取)
-
SELECT * FROM user WHERE id = ?(走主键) vsSELECT * FROM order WHERE status = ?(未建索引) - 同一事务内连续 3 次查询,观察协程是否被阻塞(协程应非阻塞切换,但 MySQL 锁可能让整个协程挂起)
结合 mysqld_exporter 查底层瓶颈
协程层“看起来快”,不代表 MySQL 没压力。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 部署
mysqld_exporter,用最小权限账号采集指标 - 压测同时关注:
-
mysql_global_status_threads_connected:是否接近max_connections -
mysql_global_status_innodb_row_lock_time_avg:平均行锁等待是否突增 -
mysql_global_status_slow_queries:慢查是否被触发(哪怕单条 SQL 耗时
-
- 若
hyperf_db_query_duration_ms平均 5ms,但innodb_row_lock_time_avg达到 8ms,说明瓶颈在 MySQL 行锁,不是协程或连接池问题
验证协程安全的边界操作
很多性能问题出在误用同步调用。
- 禁止在协程中调用
file_get_contents、curl_exec、sleep()等阻塞函数(会拖垮整个 worker) - 替换为协程客户端:
Swoole\Coroutine\Http\Client或Hyperf\HttpClient - 测试混合 IO:10 个协程里,5 个查 MySQL,5 个调第三方 HTTP 接口,观察整体 QPS 是否线性增长(协程应并行,而非串行等待)
不复杂但容易忽略










