thinkphp 无原生连接池配置,其连接复用依赖请求生命周期管理;高并发瓶颈在 mysql 的 max_connections 和 php-fpm 的 pm.max_children;swoole/cli 场景需手动 close() 防泄漏。

ThinkPHP 连接池大小在哪配?database.php 里没这个字段
ThinkPHP 默认不实现连接池,它用的是 PDO 短连接 + 连接复用(通过 think\db\Connection 的连接缓存机制),不是像 Go 或 Java 那种带 idle/max active 的池。所谓“调优连接池”,实际是调 mysql.connect_timeout、mysql.wait_timeout 和 ThinkPHP 自身的连接复用策略。
-
database.php中的'deploy' => 0表示单库,此时连接复用靠'debug' => false下的连接对象复用,开启 debug 会每次新建连接 - 真正影响并发连接数上限的是 MySQL 服务端的
max_connections,以及 PHP-FPM 的pm.max_children—— 这俩才是瓶颈源头 - 如果硬要“模拟池行为”,得自己封装连接管理器,用静态变量缓存
PDO实例,但要注意事务隔离和连接状态残留问题
高并发下连接数爆满?先看错误是不是 SQLSTATE[HY000] [2002] Connection refused
这个报错表面是连不上 MySQL,但大概率是服务端拒绝新连接,而非网络不通。原因通常是:
- MySQL 的
max_connections被打满(查SHOW STATUS LIKE 'Threads_connected';) - PHP-FPM 子进程太多,每个都持有一个未释放的 PDO 连接(尤其用了
new \think\Db()手动实例化又没及时close()) - 连接未被回收:ThinkPHP 在请求结束时自动关闭连接,但如果你在 CLI 或长生命周期场景(如 Swoole)中使用,必须手动调用
\think\Db::connect()->close() - 注意
pdo_mysql的mysqlnd驱动默认启用 persistent 连接,但 ThinkPHP 不推荐开启'persistent' => true,容易引发状态污染和连接泄漏
Db::table()->select() 为什么每次看起来都像新建连接?
不是每次都新建,而是 ThinkPHP 的连接获取逻辑有两层缓存:一是单例连接对象复用,二是查询结束后不立即 close(等 request 生命周期结束)。但以下情况会打破复用:
- 跨数据库操作:
Db::connect('mysql2')->table(...)会创建新连接实例 - 手动传入配置数组初始化:
Db::connect(['hostname' => ...])每次都 new 新连接 - 使用了
Transaction且未正确 commit/rollback,连接会被标记为“占用中”,后续同连接池请求会阻塞或新建 - CLI 命令中多次调用
Db::table(),若没显式->close(),连接会累积到进程退出
Swoole + ThinkPHP 场景下连接数失控怎么收住?
Swoole 的常驻内存特性让 ThinkPHP 默认的“请求结束自动关连接”完全失效,连接会越积越多,直到 MySQL 拒绝服务。
- 必须禁用所有自动连接复用:在
database.php中设'deploy' => 0且'debug' => false,再加'break_reconnect' => true - 每个数据库操作后主动释放:
$db = Db::name('user'); $data = $db->select(); $db->close(); - 更稳妥的做法是封装一个连接工厂,在协程上下文里做
defer关闭:go(function () { $db = Db::connect(); defer(fn() => $db->close()); ... }); - 别信“Swoole 支持连接池”的第三方扩展,ThinkPHP 官方不兼容,容易和 ORM 的 query builder 冲突,出错时堆栈难定位
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










