thinkphp 6 和 8 的长连接本质是连接池复用,非 pdo::attr_persistent;tp6 必须配置 deploy=1 于 database.php 中启用复用,swoole 环境则需 think-swoole 扩展并使用 db::pool() 调用,且 mysql max_connections 必须同步调优。

ThinkPHP 6 和 8 的“长连接”不是靠 PDO::ATTR_PERSISTENT 实现的,加了也基本无效;真正起作用的是连接池机制,但必须匹配运行环境(FPM 还是 Swoole)和配置位置,配错地方等于没配。
TP6 的 deploy=1 是最简连接复用方案(FPM 环境)
如果你还在用 PHP-FPM,别折腾持久化参数——deploy => 1 才是 TP6 唯一有效的连接复用开关。它不依赖 PDO 持久化,而是靠框架自己缓存同配置的 PDO 实例。
-
deploy => 1必须写在config/database.php的数据库配置块里,不是全局配置项 - 即使没配从库、
rw_separate => false,只要deploy => 1就会启用连接复用逻辑 - 连接复用只对「同 hostname + 同 database + 同 username」的请求生效;换库名或改账号会新建连接池
- 空闲连接不会自动释放,得手动加
pool_time => 3600(单位秒),否则连接堆积到 MySQLmax_connections耗尽
TP6/TP8 的 DbPool 需要 Swoole + think-swoole 扩展(协程环境)
DbPool 不是开箱即用的功能,它只在 Swoole 协程环境下工作,且必须通过 think-swoole 扩展启用。FPM 下直接调用 Db::pool() 会报错或退化为普通连接。
- 确认已安装
swoole >= 4.8.0和topthink/think-swoole >= 3.1.0 - 配置只生效于
config/swoole.php的db_pool节点,database.php里加任何 pool 字段都无效 - 必须显式调用
Db::pool()->table()或Db::pool()->transaction(),Db::table()和Db::transaction()仍走传统连接 -
max_active => 8是硬上限,超出的请求排队等待(默认最多等 2000ms),超时抛PoolTimeoutException
为什么 show processlist 看不到复用连接?
常见错误是误以为“长连接 = 连接一直挂着”,其实 TP6/TP8 的连接池是按需复用 + 主动回收的模型。你看到的 show processlist 是 MySQL 服务端视角,而框架层的“复用”发生在连接取出/归还池子的过程,不是连接永不关闭。
- MySQL 的
wait_timeout和interactive_timeout是被动断连机制,与应用层连接池无关 - 如果
show processlist里连接数持续上涨,大概率是:没开deploy/ 没用Db::pool()/ 事务或模型操作绕过了池子 - 用
Db::pool()后仍报Too many connections,先检查是否所有 DB 操作(尤其是事务)都改用了池化入口
MySQL 侧必须同步调优,否则连接池形同虚设
连接池再高效,也受限于 MySQL 服务端的 max_connections 上限。默认 151 完全不够高并发场景,光调 PHP 层没用。
- 每条 MySQL 连接约占用 2–3MB 内存,把
max_connections提到 500 前,先算服务器内存是否撑得住 -
wait_timeout建议设为 300~600 秒,太短会导致池中连接频繁重建,太长则空闲连接滞留 - 监控真实连接峰值不能只看
show processlist,要用SHOW STATUS LIKE 'Threads_connected'查当前活跃连接数
最容易被忽略的是:连接池不是全局单例,Swoole 下每个 Worker 进程维护自己的池子;FPM 下每个 PHP 进程也有独立复用逻辑。所以压测时看到连接数翻倍,未必是配置失效,可能是进程模型本身导致的。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











