PHP本身不内置连接池,真连接池需依赖Swoole、php-pm或ProxySQL等方案;FPM下仅支持不可控的PDO持久连接,Swoole中须在config/swoole.php启用database.enable=true并设min/max_connections,且需匹配MySQL max_connections与worker_num。

PHP本身不内置连接池,所谓“配置连接池参数”实际取决于你用的运行环境和扩展。原生 PHP-FPM 模式下没有真正意义上的连接池,只有持久连接(PDO::ATTR_PERSISTENT),它由进程级复用,不可控、易泄漏、不支持协程。真连接池需依赖 Swoole、php-pm 或数据库代理等方案。
看用的是哪种环境
不同运行模式对应完全不同的配置位置和方式:
-
Swoole 协程环境(推荐):必须用
think-swoole(ThinkPHP)或swoole/ide-helper+ 自定义池管理器。连接池参数在config/swoole.php的database节点里设置,例如:
'database' => [
'enable' => true,
'min_connections' => 5,
'max_connections' => 50,
'wait_timeout' => 3.0,
'heartbeat' => 30,
]
注意:enable 必须为 true,否则所有参数无效;database.php 里加 pool 字段是徒劳的。
-
php-pm(PHP-PM 进程管理器):靠
mysqlnd驱动缓存连接,配置在pm.config.inc中,通过进程启动时预建连接实现“伪池”,不支持动态伸缩和健康检查。 -
Laravel / Symfony 等框架:底层使用 Doctrine DBAL 或自研连接管理器,连接池能力已封装,只需在
.env或配置文件中设DB_POOL_MAX_CONNECTIONS=30类似参数(具体键名依框架版本而定)。 -
MySQL Router / ProxySQL / MaxScale:连接池逻辑在中间件层,PHP 只需普通 PDO 连接,参数配置在代理服务端,比如 MySQL Router 的
connection_pool_size = 100。
关键参数怎么设才合理
不能只看文档填数字,得对齐三层限制:
立即学习“PHP免费学习笔记(深入)”;
-
MySQL 侧:确认
SHOW VARIABLES LIKE 'max_connections';≥ 你设的max_connections,否则多余连接直接被拒 -
Worker 数量:Swoole 的
worker_num是并发上限,若设为 4,哪怕池里有 100 个连接,最多也只有 4 个请求能同时取到连接 -
协程并发量:
go(function () { ... });启的协程数若远超max_connections,就会排队等待,不是并行执行
建议起步值:min_connections = 5(避免冷启动延迟),max_connections = 20~50(中小业务),再根据压测中 ConnectionPoolTimeoutException 出现频率调整 wait_timeout(通常 2~5 秒)。
怎么验证改生效了
别只信配置文件,要实测是否真复用:
- 在控制器里打印
DB::getPdo()返回的实例 ID,同一协程内多次调用应返回相同对象 - 查 MySQL 当前连接数:
SHOW STATUS LIKE 'Threads_connected';,高并发下应稳定在min_connections~max_connections区间,而不是随请求暴增 - 用
Swoole\Coroutine\Channel查当前池中空闲连接数(如使用 think-swoole)
常见踩坑点
- 在 FPM 下硬配
max_connections—— 完全无效,FPM 每次请求都是新进程,无池可言 - 只调大
max_connections,没调 MySQL 的max_connections—— 日志报Too many connections - 没开
enable=true,其他参数全被忽略 - 用 PDO 持久连接当连接池用 —— 进程崩溃后连接不释放,容易耗尽 MySQL 连接数



















