Yii框架无内置连接池,实际依赖PDO连接复用、主从路由与Schema缓存协同优化:1)禁用PDO::ATTR_PERSISTENT以防连接泄漏;2)slaves配置仅为健康检查式连接分发;3)enableSchemaCache才是降低元数据查询开销的核心。

Yii 框架本身没有内置“连接池”概念,它用的是 PDO 连接复用机制,所谓“连接池”其实是开发者对 enablePersistent(持久连接)或主从配置下连接分发行为的误称。真正在高并发下起作用的,是连接复用 + 主从路由 + Schema 缓存三者协同,不是靠开启某个开关就能自动变出连接池。
为什么 PDO::ATTR_PERSISTENT => true 在 Yii 中基本不用
很多人看到 PDO 支持持久连接,就直接在 attributes 里设成 true,结果发现连接数疯涨、MySQL 报 Too many connections。原因很直接:
- PHP-FPM 是多进程模型,每个 worker 进程会维护自己的持久连接,不会跨进程共享
- 持久连接不自动回收,空闲连接长期占着 MySQL 的
wait_timeout资源 - Yii 的
Connection类在close()时并不会真正断开,而是标记为“可复用”,但前提是没设PDO::ATTR_PERSISTENT - 一旦开了
PDO::ATTR_PERSISTENT,PDO 就绕过 Yii 的连接管理逻辑,导致事务状态、字符集等上下文错乱
结论:生产环境禁用 PDO::ATTR_PERSISTENT,用 Yii 原生的连接复用机制更可控。
主从配置里的 slaves 不是连接池,但能缓解连接压力
你配了 slaves 数组,不代表连接被“池化”了,只是 Yii 在执行只读查询时,会从这个数组里挑一个节点建立新连接(或复用已有连接)。关键点在于:
- 每个 slave 节点仍走独立的 PDO 连接生命周期,没有跨节点连接共享
-
slaveConfig里的attributes只影响从库连接,比如可以单独设PDO::ATTR_TIMEOUT => 2,比主库更激进地断开失败连接 -
shuffleMasters => true是让多个主库之间随机选,避免单点过载,但它不减少连接总数,只是分散 - 如果从库连接失败,Yii 会缓存失败状态(靠
serverStatusCache),后续请求跳过该节点,直到serverRetryInterval到期
所以这不是连接池,是带健康检查的连接分发器 —— 它的价值在于容错和负载分散,不是连接复用效率提升。
enableSchemaCache 才是实际降低连接开销的大招
很多人以为优化连接就是调 timeout 或开持久化,其实最常触发额外连接的,是 Schema 查询。每次 ActiveRecord 第一次访问某张表,Yii 默认会查 INFORMATION_SCHEMA 获取字段、索引、主键等元数据 —— 这个过程会新建一个临时 PDO 连接(哪怕主连接已存在)。
- 必须同时启用
enableSchemaCache => true和指定有效的schemaCache组件(如'schemaCache' => 'cache') -
schemaCacheDuration推荐设为3600(1小时),太短起不到效果,太长会导致结构变更后缓存不刷新 - 如果
cache组件本身没启用(比如 Redis 不通、file cache 权限不对),Yii 会静默退回到无缓存模式,且不报错 —— 这是最容易被忽略的失效点 - 验证是否生效:改一个 Model 的表结构,清缓存后首次访问该 Model,看 MySQL 慢日志里有没有
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS类查询
这才是真正减少“非业务连接”的核心配置,比折腾 PDO::ATTR_PERSISTENT 实在得多。
真正需要连接池的场景(比如微服务间高频 DB 访问),得上外部方案:ProxySQL、MySQL Router,或者用 Swoole 配合协程连接池 —— Yii 作为传统 FPM 框架,它的“连接池”本质是连接复用策略 + 合理的超时与缓存组合,不是靠一个参数开关就能搞定的。



















