跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Yii2的数据库连接池怎么实现_使用pmmp/yii2-connection-pool【操作】

pmmp/yii2-connection-pool 是专为 Swoole 协程设计的 PDO 连接池扩展,需在协程上下文手动初始化、单例注入 DI 容器,并严格通过 get()/put() 管理连接;不适用于 PHP-FPM/Apache,且无内置健康检查。 Yii2 本身没有内置连接池,
pmmp/yii2-connection-pool
是第三方扩展 Yii2 的
yii\db\Connection
默认每次请求新建/复用 PDO 连接,但底层不维护连接池——它依赖 PHP-FPM 进程生命周期或 Swoole 协程环境下的连接复用机制,不是传统意义上的“连接池”。
pmmp/yii2-connection-pool
是为 Swoole(尤其是协程模式)设计的轻量封装,本质是用
Swoole\Coroutine\Channel
管理预创建的
PDO
实例。 常见错误现象:
Fatal error: Uncaught Swoole\Error: Unable to create channel
或连接数远超预期,多因未在协程上下文初始化、或在非 Swoole 环境(如普通 PHP-FPM)中强行启用。 只适用于 Swoole >= 4.5 + 协程模式(
enable_coroutine => true
),PHP-FPM / Apache 下直接报错或静默失效 必须在协程启动后、首次数据库操作前完成连接池初始化,不能放在
config/web.php
顶层执行
maxIdle
和
maxActive
不是 MySQL 的
max_connections
,而是池内对象数量,设太高会撑爆内存,太低则频繁创建销毁抵消性能收益
pmmp/yii2-connection-pool
的正确初始化时机和位置 它不能像原生
db
组件那样在配置文件里声明即生效。必须手动在协程入口(如 Swoole HTTP Server 的
onRequest
回调、或 Yii2 的
Bootstrap
类中检测协程环境后调用)。 典型错误:在
common/config/main.php
中直接 new Pool() —— 此时无协程上下文,
Channel
创建失败;或在控制器 action 里每次 new 一个池,导致连接泄漏。 推荐在自定义
Bootstrap
类的
bootstrap()
方法中,用
if (Swoole\Coroutine::getCid() > 0)
判断是否已进入协程 池实例应单例化并注入到 DI 容器,避免重复初始化;例如绑定为
'dbPool'
,后续通过
Yii::$app->get('dbPool')
获取 初始化时传入的
config
数组需包含完整 PDO DSN 信息,且
username
/
password
必须显式传入,不能复用原
db
组件配置里的敏感字段(因组件可能已被初始化) 从连接池获取连接的实际写法和常见漏点 拿到池对象后,不能直接调用
open()
或
createConnection()
,必须用
get()
并配合
try/finally
归还——这是最容易被忽略的一步,漏掉会导致连接永远卡在池中,池迅速耗尽。 WOC-YII开源站群管理系统1.3 WOC-YII是rschome.com基于yii framework 1.1.8框架所开发的一款开源简易站群管理系统。它的功能与WOC完全一样。目前版本为V1.3,新版本正在开发中,同时欢迎大家参与到开发中来! WOC-YII 1.3在1.2的基础上优化了登录系统(密码加密),优化了权限控制系统,新增seo管理功能,新增自动安装向导! 程序框架:yiiframework1.1.8 配置文件:p 下载 示例片段:
$pool = Yii::$app->get('dbPool'); $conn = $pool->get(); // 阻塞直到有空闲连接 try { $stmt = $conn->prepare('SELECT * FROM user WHERE id = ?'); $stmt->execute([$id]); return $stmt->fetchAll(); } finally { $pool->put($conn); // 必须放回!不可省略 }
$pool->get()
在池空时默认阻塞,可传
timeout
参数(单位秒)避免无限等待,例如
$pool->get(0.5)
不要对返回的
$conn
调用
close()
或
__destruct()
,它不是真实 PDO 连接,只是池管理的代理对象 若在事务中使用,需确保整个事务块都在同一
$conn
上执行,且
put()
放在事务提交/回滚之后 性能与兼容性边界:什么时候不该用这个包 它解决的是高并发协程场景下 PDO 创建开销问题,但代价是内存占用和逻辑复杂度上升。很多项目其实根本不需要。 QPS PDO::ATTR_PERSISTENT => true)+ MySQL 连接复用已足够,加池反而增加调度负担 使用
yii2-redis
或其他非 PDO 数据源时,该包完全不适用——它只包装 PDO,不涉及任何 Redis、MongoDB 等协议 若项目混用 Swoole 协程和同步阻塞逻辑(比如部分命令行任务仍走传统 FPM 模式),必须严格隔离配置,否则
get()
在非协程环境会死锁 最常被忽略的点:这个包不处理连接健康检查。如果 MySQL 主动断开空闲连接(
wait_timeout
),池里的连接可能变成“僵尸”,需要自己加
PDO::ping()
或设置
validationQuery
做探活——但它本身没提供这个钩子。

相关文章