min_connections仅控制初始化预创建连接数,不保活;真正决定连接复用的是max_idle_time与mysql wait_timeout的协同配置及心跳机制。

Hyperf 中数据库连接池的 min_connections 不等于“长连接保活”
直接说结论:min_connections 只控制连接池初始化时预创建的最小空闲连接数,它本身不保证连接长期存活,也不等同于 MySQL 的 wait_timeout 或连接保活机制。很多用户配了 min_connections: 10 就以为“10 个长连接永远在线”,结果发现连接仍会断开或被服务端主动 kill——这是因为连接是否复用、是否超时,取决于连接池的回收策略 + 数据库服务端配置 + 客户端心跳行为三者共同作用。
为什么 min_connections 配得高却还是频繁重建连接?
常见现象:明明设了 min_connections: 5,但 SHOW PROCESSLIST 里活跃连接忽高忽低,甚至查日志看到反复出现 Connection refused 或 MySQL server has gone away。根本原因在于:
-
min_connections只在 Pool 初始化时生效,后续连接空闲超时(max_idle_time)后会被自动销毁,哪怕池中连接数掉到低于min_connections - Hyperf 默认使用 Swoole 协程 MySQL 客户端,其底层连接是协程安全的,但不自动发送心跳包;若 MySQL
wait_timeout(默认 28800 秒)小于连接空闲时间,连接会被服务端关闭 -
max_idle_time必须显式配置且 ≤ MySQL 的wait_timeout,否则空闲连接大概率在下次复用前已被服务端断开
正确配置连接池以支撑稳定复用
关键不是堆高 min_connections,而是协同调整三项参数并验证效果:
- 设置
min_connections: 2(够用即可,过高浪费内存和 DB 端资源) - 显式配置
max_idle_time: 25920(即 7.2 小时,必须 wait_timeout,建议留 10% 缓冲) - 启用
connect_timeout: 3和timeout: 10避免卡死 - 在
config/autoload/databases.php中确保options包含PDO::ATTR_PERSISTENT => false(Hyperf 的协程客户端不支持持久化连接,设为true会出错) - 如需更激进保活,可配合
onConnect回调执行SELECT 1,但注意增加 RT 开销
示例片段(config/autoload/databases.php):
'default' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', 3306'),
'database' => env('DB_DATABASE', 'hyperf'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'fetch_mode' => PDO::FETCH_ASSOC,
'pool' => [
'min_connections' => 2,
'max_connections' => 32,
'connect_timeout' => 3.0,
'wait_timeout' => 3.0,
'heartbeat' => -1,
'max_idle_time' => 25920,
],
],
如何验证连接是否真正复用?
不能只看配置,要观测运行态:
- 用
swoole_table或var_dump($pool->getStats())查看active_connections和idle_connections是否稳定波动(而非清零后重拉) - 开启 MySQL 慢日志 + general_log,观察相同 client_id 的连接是否被重复使用(注意 Swoole 协程下 client_id 是进程+协程 ID 组合)
- 模拟低频请求间隔 >
max_idle_time,确认是否会触发重连——如果会,说明max_idle_time或 MySQLwait_timeout配置不匹配
真正影响长连接复用的,从来不是 min_connections 这个“起点”,而是 max_idle_time 和数据库服务端 timeout 的对齐精度,以及有没有在连接复用前做有效性校验。漏掉任一环,连接池就只是“看起来很满”。











