ThinkPHP 无内置连接池,所谓“连接池”实为 PDO 长连接或 Swoole 协程下第三方组件模拟的复用机制;FPM 模式下 'persistent' 基本无效,仅 CLI+Swoole 协程模式可真正复用,需开启 SWOOLE_HOOK_ALL、禁用 auto_close、手动归还连接,并调优 MySQL wait_timeout 等参数。

ThinkPHP 连接池配置没生效?先确认是否真启用了连接池
ThinkPHP 本身不内置数据库连接池,所谓“连接池”实际是 PDO 的长连接(PDO::ATTR_PERSISTENT)或由 Swoole/Workerman 等协程服务器配合第三方组件(如 topthink/think-swoole)模拟的连接复用机制。直接在 database.php 里加 'persistent' => true 并不能自动形成连接池,它只对单次 CLI 或 FPM 请求内的多次查询有效,且受 PHP 进程生命周期限制。
常见错误现象:mysql has gone away 错误变多、连接数监控显示始终等于并发请求数、SHOW PROCESSLIST 里大量 Sleep 状态连接未复用。
- 确认运行环境:FPM 模式下
persistent基本无效,因为每个请求结束会销毁连接;只有 CLI + Swoole 协程模式才能真正复用连接 - 检查是否已启用协程驱动:Swoole 必须开启
hook_flags = SWOOLE_HOOK_ALL,否则 PDO 不会被协程化,连接仍会阻塞并新建 - 验证配置是否被加载:在控制器中打印
Db::getConfig(),确认'persistent'值为true,且'deploy'未设为1(读写分离会绕过持久化逻辑)
使用 think-swoole 启用连接池时,DB 配置必须关闭自动释放
think-swoole 提供了 ConnectionPool 类封装,但默认行为仍可能在每次请求后调用 close(),导致连接被归还前就断开。关键在于禁用 ThinkPHP 自动关闭连接的动作,并交由池管理。
- 在
config/database.php中设置:'auto_close' => false(该配置项存在但文档极少提及) - 确保数据库初始化发生在 Worker 启动时,而非每次请求:用
Swoole\Coroutine\Channel或静态属性缓存Db实例,避免重复 new - 若使用
Db::connect()手动获取连接,必须显式调用$pool->put($conn)归还,不能依赖析构函数——协程退出快于 GC 触发,连接大概率泄漏
示例片段(非完整):
$pool = Db::getPool();<br>$conn = $pool->get();<br>try {<br> $result = $conn->table('user')->find();<br>} finally {<br> $pool->put($conn); // 必须手动归还<br>}
连接复用率低?检查事务和长查询是否阻塞连接归还
连接池吞吐下降最常见的原因是连接被长时间占用却未释放,典型场景是未提交的事务、大字段查询、sleep() 调试残留、或协程内同步 I/O(如 file_get_contents)阻塞当前协程,导致连接卡在 get() 阶段无法归还。
- 所有事务块必须有明确的
commit()或rollback(),建议用try/catch/finally包裹,finally中强制归还连接 - 避免在协程中执行同步 MySQL 查询以外的阻塞操作;若必须调用外部 HTTP,改用
Swoole\Coroutine\Http\Client - 监控连接等待时间:在
get()前记录时间戳,超 500ms 打印警告日志,快速定位卡点
MySQL 服务端参数影响连接池效果,别只调 PHP 端
即使 PHP 层连接复用正常,MySQL 的 wait_timeout 和 interactive_timeout 设置过小(如默认 28800 秒),会导致空闲连接被服务端主动断开,下次复用时触发重连,反而增加延迟与失败率。
- 将 MySQL 的
wait_timeout设为至少 300(5 分钟),避免频繁断连;注意该值不能大于 PHP 的max_execution_time - 检查
max_connections是否足够:连接池最大连接数 × Worker 数量 ≤ MySQL 总连接上限,否则新连接会直接被拒绝,报错Too many connections - 开启
skip-name-resolve减少 DNS 解析开销,尤其在容器或云环境中,域名解析失败会导致连接初始化延迟甚至超时
连接复用不是开个开关就完事的事,它横跨 PHP 运行模式、协程调度、PDO 行为、MySQL 配置四层,漏掉任意一层都可能让复用率趋近于零。最常被忽略的是:你以为在用连接池,其实只是把连接从“每次新建”换成了“每次重建”。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











