hyperf的pool.max_connections应按峰值qps×平均耗时+余量估算,建议单源起步50、总和控制在db侧max_used_connections的50%~75%,并配对调整wait_timeout(5.0秒)、max_idle_time(30秒)及thread_cache_size(≥16)。

Hyperf 项目里 MySQL 客户端最大连接数不能直接套用 MySQL 服务端的 max_connections,必须按连接池维度单独配置——否则哪怕数据库允许 2000 连接,Hyperf 侧最多只用 10 个,照样扛不住并发。
Hyperf 的 pool.max_connections 怎么设才不拖慢请求
Hyperf 默认 pool.max_connections = 10,这是开发环境够用的值,但线上高并发场景下会成为瓶颈。真实压测中,QPS 超过 300 后就容易出现连接等待超时或 wait_timeout 触发断连。
- 先看业务实际并发:用
ab或wrk模拟真实接口,观察hyperf:monitor输出的db.pool.used峰值 - 再结合 MySQL 服务端资源:如果 DB 实例
Max_used_connections历史峰值是 400,那 Hyperf 侧所有数据源加起来的pool.max_connections总和建议控制在 200~300(留余量防毛刺) - 单个数据源起步值可设为
50,上线后按pool.wait_count和pool.wait_time监控指标微调;超过100需同步检查 MySQL 的thread_cache_size是否 ≥ 16
为什么改了 pool.max_connections 还卡在连接获取上
常见错觉:调大了连接池上限,但请求仍卡在 wait_timeout 或 pool.wait_timeout 报错。本质是连接没被及时释放,或者池子“看起来满”实则被长事务/慢查询占着不动。
-
pool.wait_timeout默认是3.0秒,但若 MySQL 的wait_timeout设为60秒,而业务 SQL 平均执行 800ms,那连接复用率低、空闲堆积多,反而加剧争抢 - 必须配对调整:
pool.max_idle_time建议设为30(比 MySQLwait_timeout小一半),避免连接池保留大量“将死未死”的连接 - 检查代码里有没有漏掉
$connection->close()或未用try-finally包裹 DB 操作——Hyperf 不像传统框架自动回收协程内连接
MySQL 服务端 max_connections 和 Hyperf 连接池的关系
两者不是 1:1 映射,而是“池子总数 ≤ 服务端上限 × 安全系数”。盲目把 MySQL 的 max_connections 调到 2000,而 Hyperf 只开 20 个连接,既浪费 DB 资源,又掩盖应用层连接泄漏问题。
- 查 MySQL 当前负载:
SHOW STATUS LIKE 'Threads_connected';和SHOW STATUS LIKE 'Max_used_connections';,如果后者长期 > 90%max_connections,优先查慢 SQL 和连接泄漏,而不是加池子 - Hyperf 多数据源场景下,每个
db.name都有独立连接池,总连接数 = Σ(pool.max_connections),务必汇总计算,别只盯单个配置项 - 系统级限制必须同步检查:
ulimit -n至少要 ≥max_connections × 2,否则 MySQL 启动时会静默降级,日志里只报Could not increase number of max_open_files
真正难的不是算出那个数字,而是让每个连接从 acquire 到 release 的路径清晰可控——Hyperf 协程环境下,连接生命周期脱离了传统线程绑定模型,稍不注意就会在异常分支里“丢连接”。











