yii2无内置数据库连接池,实际依赖pdo连接复用、主从分发与schema缓存协同优化:1)禁用pdo::attr_persistent防连接泄漏;2)slaves仅用于健康检查式读请求分发;3)enableschemacache才是降低元数据查询开销的核心。

Yii2 没有数据库连接池,别被“连接池”这个词带偏了——它压根不提供连接池功能,所谓“Yii2连接池优化”,本质是误传或混淆概念。
你真正能调的,就三件事:PDO连接复用、主从分发逻辑、Schema元数据缓存。下面直说怎么做、为什么、容易踩什么坑。
为什么 PDO::ATTR_PERSISTENT => true 在 Yii2 生产环境必须禁用
开了这个参数,每个 PHP-FPM worker 进程会自己留着一个 MySQL 连接不释放,结果就是:
- MySQL 的
max_connections很快被占满,报Too many connections - 连接空闲时受 MySQL
wait_timeout控制,超时后下次用会触发MySQL server has gone away - Yii 的事务状态、字符集、SQL mode 等上下文可能错乱,因为 PDO 绕过了 Yii 的
Connection::close()管理流程
正确做法是保持 'attributes' => [](即不设 PDO::ATTR_PERSISTENT),让 Yii 自己控制连接生命周期:请求结束自动标记为可复用,下个请求来时直接重用已有连接。
slaves 配置不是连接池,但能帮你扛住读压力
你在 components['db'] 里配了 slaves 数组,只是告诉 Yii:“只读查询可以去这些地址里挑一个连”,但它不会预先建好一堆连接等着用。
- 每个 slave 节点仍走独立的 PDO 连接创建/复用流程,没跨节点共享
-
slaveConfig['attributes']可单独设PDO::ATTR_TIMEOUT或PDO::MYSQL_ATTR_CONNECT_TIMEOUT,建议比主库更激进(比如设为 2 秒),避免卡死 - 节点失败后,Yii 会写入
serverStatusCache缓存失败状态,默认 30 秒内跳过该节点 —— 这个机制依赖你配置了有效的缓存组件(如redis),否则降级为每次都试
enableSchemaCache 才是降低连接开销最狠的一招
很多人盯着连接数看,却不知道 ActiveRecord 第一次访问某张表时,Yii 默认会新建一个临时 PDO 连接去查 INFORMATION_SCHEMA。这个动作不走主连接复用逻辑,每张新表都可能触发一次额外连接。
- 必须同时启用:
'enableSchemaCache' => true+ 配置有效的'schemaCache' => 'cache'(指向 Redis 或 APCu) - 强烈建议配
'schemaCacheDuration' => 3600(1 小时),否则缓存永不过期,表结构变更后查不到新字段;也不建议设为 0,会导致缓存键无限膨胀、连接池被长连接占满 - 如果用了
FileCache当schemaCache,高并发下文件锁竞争会让整个 DB 初始化变慢,生产环境禁用
真要连接池?换运行模型,别硬改 Yii2
PHP-FPM 天然不适合连接池,因为进程一结束,池里连接就全丢。想用连接池,得切到常驻内存模型:
- Swoole 协程 +
yii2-swoole扩展,它提供了ConnectionPool类,支持预热、最大连接数、空闲超时等标准池参数 - Hyperf 或 EasySwoole 框架,它们的 MySQL 连接池组件成熟稳定,兼容 PDO 接口,迁移成本比硬改 Yii2 低得多
- ProxySQL 类代理方案,PHP 完全无感,所有连接复用、读写分离、故障转移都在代理层做,适合不能动框架的遗留系统
最后提醒一句:如果你在 FPM 下看到连接数居高不下,先检查是不是 enableSchemaCache 开了但没配 schemaCacheDuration,这是线上最常被忽略的连接耗尽原因。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











