thinkphp 8 连接池配置入口在 config/swoole.php 的 database 节点,需启用 enable=true 并设置 min_connections、max_connections 等参数;database.php 中添加 pool 字段无效,db::table() 默认不走连接池,必须显式调用 db::pool() 才生效。

ThinkPHP 本身不带原生连接池,所谓“配连接池”,实际取决于你用的是哪种运行环境和扩展。FPM 下根本没连接池;只有在 Swoole 协程环境下,配合 think-swoole 才能真正启用可控的连接池。
ThinkPHP 8 连接池配置入口在哪
不是 database.php,硬加 pool_size 或 max_connections 字段完全无效。正确位置是 config/swoole.php 的 database 节点:
'database' => [
'enable' => true,
'min_connections' => 5,
'max_connections' => 50,
'wait_timeout' => 3.0,
'heartbeat' => 30,
],
-
enable必须设为true,否则所有参数被忽略,仍走短连接 -
min_connections是 Worker 启动时预热创建的连接数,设太低会导致首请求延迟 -
max_connections是单个 Worker 进程内池子的最大总连接数(空闲+忙碌),不是全局上限 -
wait_timeout单位是秒,协程等待空闲连接超时后抛ConnectionPoolTimeoutException
为什么 Db::table() 配了池还是连不上
因为 Db::table() 默认不走池——它永远调用传统 Db::connect()。必须显式使用 Db::pool() 才进入池逻辑:
- ✅ 正确:
Db::pool()->table('user')->select() - ❌ 错误:
Db::table('user')->select()(绕过池) - ❌ 错误:
Db::transaction(...)(默认非池化,要用Db::pool()->transaction(...)) - ❌ 错误:模型类里直接
self::where(...)->find()(底层仍走Db::connect())
常见现象是压测时 Too many connections 照旧,本质是 90% 的查询根本没进池。
连接池生效但 QPS 上不去,卡在哪
连接池只是其中一环,三处硬限制必须对齐:
- MySQL 侧:
show variables like 'max_connections';必须 ≥ 每个 Worker 的max_connections×swoole.server.worker_num - Swoole 侧:
swoole.server.worker_num决定了最多几个进程能并发取连接;设成 2,哪怕池里有 100 连接也只用得上 2 个 - 协程侧:一个 Worker 内启了 200 个协程去查库,但池子只有 8 个连接,剩下 192 个协程全在排队等
wait_timeout
验证是否真复用:在同一个协程里连续两次调 Db::pool()->getPdo(),打印句柄 ID,相同才说明复用成功。
CLI 场景下连接池怎么关
CLI 不是长生命周期服务,think-swoole 的池机制不适用。强行在命令里调 Db::pool() 会泄漏连接,因为没有 Worker 生命周期来自动回收。
- CLI 命令应禁用池,回归传统短连接(删掉
config/swoole.php中的database.enable) - 若必须复用,手动控制:
$db = Db::connect(); ... $db->close();,不依赖自动销毁 - 切勿在
for循环里反复Db::pool()->table()—— 每次都可能从池里拿新连接,且 CLI 不释放
最容易被忽略的是:Swoole 环境下改了配置不 reload worker,或用了 mysql 驱动而非 mysqlnd,导致 PDO 实例非协程安全,复用反而引发 MySQL server has gone away。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











