thinkphp 本身没有数据库连接池,pool 和 max_connections 是第三方扩展伪配置;真实连接由 pdo 决定,长连接靠 'persistent' => true;监控需直查 mysql 的 threads_connected 或 processlist,而非 tp 的 db::getpdo()。

ThinkPHP 本身没有数据库连接池,别被“pool”配置误导
ThinkPHP 6.x 和 5.1 的数据库配置里出现 pool 或 max_connections 字段,只是部分第三方扩展(如 think-swoole 插件)加的伪层封装,框架原生 Db 类根本不识别这些配置项。真实连接行为完全由 PDO 决定:'persistent' => true 是长连接复用,false 是短连接;'deploy' => 1(读写分离)会额外触发一次 PDO::__construct,但仍是单次请求绑定单个 PDO 实例。所谓“连接池监控”,本质是监控 MySQL 服务端的连接状态,不是 TP 自己维护的池。
必须直查 MySQL 的 Threads_connected 才算真实连接数
TP 的 Db::getPdo() 只返回当前请求的 PDO 对象,无法反映全局连接占用。要判断是否快打满 max_connections,只能绕过框架查 MySQL:
- 执行
SHOW STATUS LIKE 'Threads_connected'—— 返回当前所有连接数(含 Sleep 状态) - 更精准用
SELECT COUNT(*) FROM information_schema.PROCESSLIST WHERE COMMAND != 'Sleep'—— 排除空闲连接,只统计活跃会话 - 注意权限:MySQL 用户必须有
PROCESS权限,线上常被禁用,得提前申请 - 别信
Time字段判断“慢连接”:TP 中事务未提交时,SHOW PROCESSLIST显示状态可能是Query,但实际卡在 PHP 层,不是 SQL 执行慢
用 Redis 做应用层连接计数器,适合无 PROCESS 权限场景
当无法开通 MySQL 的 PROCESS 权限时,可在 TP 应用层用 Redis 模拟连接水位:
- 在
think\db\Connection::connect()成功后,执行Redis::incr('db:active_connections') - 在请求生命周期结束处(如中间件
terminate())或事务回调中,执行Redis::decr('db:active_connections') - 异常路径必须兜底:用
register_shutdown_function()补充decr,否则连接计数会持续漂高 - 写入本地临时文件作为降级备份,防 Redis 故障导致监控失明
Prometheus 抓取的是 MySQL 服务端指标,不是 ThinkPHP 的
想用 Prometheus 监控数据库连接状态,目标必须是 MySQL 本身,不是 ThinkPHP 进程。常见错误是试图在 TP 里暴露 “当前用了几个连接” 这类指标——它既不准确,也没意义。正确做法是:
- 部署
mysqld_exporter,用最小权限账号连接 MySQL,拉取mysql_global_status_threads_connected等原生指标 - 在 Grafana 中直接看
Threads_connected / @@max_connections比值,设阈值告警(如 >0.85) - 别把 TP 的 QPS、响应时间指标和 MySQL 连接指标混在一个面板里分析——它们属于不同层级,因果关系不能倒置:连接打满是结果,不是原因
真正容易被忽略的是连接泄漏的根因定位:90% 的 Too many connections 都来自未关闭的事务或长查询卡住连接,而不是并发量真高。先查 SHOW PROCESSLIST 里 Time 值大的记录,再反向追踪 TP 代码里哪段 transaction() 缺了 rollback() 或没包 try/catch。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











