Hyperf连接池需正确配置与代码配合才能复用连接;默认min_connections=1、max_connections=10不适用中高并发,连接未归还、上下文绑定失败、绕过池直连PDO或pipeline未exec均导致反复建连;max_connections须≤DB侧值×0.7,wait_timeout建议5.0~8.0秒,max_idle_time必须小于数据库wait_timeout,否则产生僵尸连接。

Hyperf连接池不是“开了就自动复用”的黑盒,它依赖正确配置和代码配合才能真正避免频繁建连。默认配置下,min_connections 为 1、max_connections 为 10,完全无法支撑中高并发场景,反而会因连接争抢触发大量 WaitTimeoutException。
为什么连接还是在反复创建?
根本原因不是连接池没起作用,而是连接未被归还或未命中复用路径:
-
Context::get($key)检查协程上下文失败时,才会走连接池取连接;若中间件、事务或异常打断了协程上下文绑定(比如手动$connection->close()或跨协程传递连接对象),后续请求就无法复用 - 使用原生 PDO 实例(非
Hyperf\DbConnection\ConnectionInterface)绕过连接池,直接 new PDO(),等于完全弃用池机制 - Redis 或 MySQL 的
pipeline()/multi()调用后未执行exec(),连接被当前协程长期持有,池中空闲连接数持续为 0
关键参数必须联动调整
单独改 max_connections 没用,必须结合负载与数据库侧限制反推:
- 先查 DB 真实
max_connections:PostgreSQL 执行SHOW max_connections;,MySQL 执行SHOW VARIABLES LIKE 'max_connections'; -
max_connections必须 ≤ DB 侧值 × 0.7(例如 DB 是 500,Hyperf 最多设 350),预留空间给备份、监控等后台任务 -
min_connections别设 0,生产环境建议 ≥ 2;冷启动时若为 0,首波请求会集体卡在建连上 -
wait_timeout生产建议 5.0~8.0 秒,太小(如 1.0)会导致瞬时抖动就被抛异常,太大(如 15.0)则掩盖连接泄漏问题
如何验证连接是否真正在复用?
不能只看日志有没有报错,要盯住两个实时指标:
- 用
SELECT count(*) FROM sys_stat_activity;(PostgreSQL)或SHOW STATUS LIKE 'Threads_connected';(MySQL)查服务端真实连接数,如果长期接近max_connections,说明池子不够或连接没归还 - 在代码里调用
$pool->getCurrentConnections()和$pool->getConnectionsInChannel(),计算idle_connections / total_connections比值;健康状态应稳定在 0.3~0.6 区间,长期 ≈ 0 是泄漏信号 - 开启
enable_jmx: true后,通过 JConsole 连接查看hyperf_db_pool_used_connections峰值曲线,若该值紧贴max_connections运行,就是危险临界点
最易被忽略的是 max_idle_time 和数据库 wait_timeout 的大小关系——它不只影响空闲连接回收,更决定取出连接时是否大概率失效。配反了不会立刻报错,但会在凌晨低峰期悄悄积累一堆“僵尸连接”,等白天流量一来全崩。


















