pmmp/yii2-connection-pool 是专为 Swoole 协程设计的 PDO 连接池扩展,需在协程上下文手动初始化、单例注入 DI 容器,并严格通过 get()/put() 管理连接;不适用于 PHP-FPM/Apache,且无内置健康检查。
Yii2 本身没有内置连接池,
是第三方扩展
Yii2 的
默认每次请求新建/复用 PDO 连接,但底层不维护连接池——它依赖 PHP-FPM 进程生命周期或 Swoole 协程环境下的连接复用机制,不是传统意义上的“连接池”。
是为 Swoole(尤其是协程模式)设计的轻量封装,本质是用
管理预创建的
实例。
常见错误现象:
或连接数远超预期,多因未在协程上下文初始化、或在非 Swoole 环境(如普通 PHP-FPM)中强行启用。
只适用于 Swoole >= 4.5 + 协程模式(
),PHP-FPM / Apache 下直接报错或静默失效
必须在协程启动后、首次数据库操作前完成连接池初始化,不能放在
顶层执行
和
不是 MySQL 的
,而是池内对象数量,设太高会撑爆内存,太低则频繁创建销毁抵消性能收益
的正确初始化时机和位置
它不能像原生
组件那样在配置文件里声明即生效。必须手动在协程入口(如 Swoole HTTP Server 的
回调、或 Yii2 的
类中检测协程环境后调用)。
典型错误:在
中直接 new Pool() —— 此时无协程上下文,
创建失败;或在控制器 action 里每次 new 一个池,导致连接泄漏。
推荐在自定义
类的
方法中,用
判断是否已进入协程
池实例应单例化并注入到 DI 容器,避免重复初始化;例如绑定为
,后续通过
获取
初始化时传入的
数组需包含完整 PDO DSN 信息,且
/
必须显式传入,不能复用原
组件配置里的敏感字段(因组件可能已被初始化)
从连接池获取连接的实际写法和常见漏点
拿到池对象后,不能直接调用
或
,必须用
并配合
归还——这是最容易被忽略的一步,漏掉会导致连接永远卡在池中,池迅速耗尽。
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
下载
示例片段:
在池空时默认阻塞,可传
参数(单位秒)避免无限等待,例如
不要对返回的
调用
或
,它不是真实 PDO 连接,只是池管理的代理对象
若在事务中使用,需确保整个事务块都在同一
上执行,且
放在事务提交/回滚之后
性能与兼容性边界:什么时候不该用这个包
它解决的是高并发协程场景下 PDO 创建开销问题,但代价是内存占用和逻辑复杂度上升。很多项目其实根本不需要。
QPS PDO::ATTR_PERSISTENT => true)+ MySQL 连接复用已足够,加池反而增加调度负担
使用
或其他非 PDO 数据源时,该包完全不适用——它只包装 PDO,不涉及任何 Redis、MongoDB 等协议
若项目混用 Swoole 协程和同步阻塞逻辑(比如部分命令行任务仍走传统 FPM 模式),必须严格隔离配置,否则
在非协程环境会死锁
最常被忽略的点:这个包不处理连接健康检查。如果 MySQL 主动断开空闲连接(
),池里的连接可能变成“僵尸”,需要自己加
或设置
做探活——但它本身没提供这个钩子。
pmmp/yii2-connection-poolyii\db\Connectionpmmp/yii2-connection-poolSwoole\Coroutine\ChannelPDOFatal error: Uncaught Swoole\Error: Unable to create channelenable_coroutine => trueconfig/web.phpmaxIdlemaxActivemax_connectionspmmp/yii2-connection-pooldbonRequestBootstrapcommon/config/main.phpChannelBootstrapbootstrap()if (Swoole\Coroutine::getCid() > 0)'dbPool'Yii::$app->get('dbPool')configusernamepassworddbopen()createConnection()get()try/finally
$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)$connclose()__destruct()$connput()yii2-redisget()wait_timeoutPDO::ping()validationQuery