原生PHP无法实现真正连接池,因PHP-FPM下请求独占进程且连接随脚本结束关闭,mysql_pconnect已废弃;仅Swoole协程环境可通过Coroutine\MySQL配合Channel手动实现连接池管理。

为什么原生 PHP 无法真正实现连接池
PHP-FPM 模式下每个请求独占一个进程/线程,mysqli 或 PDO 连接在脚本结束时自动关闭,mysql_pconnect 已被废弃且不支持现代 MySQL 协议。所谓“连接池”在传统 PHP 中只是复用单个长连接,无法跨请求共享连接资源——这不是池,是假象。
Swoole 的 Coroutine\MySQL 是唯一可行路径
只有 Swoole 协程环境下,才能在协程间安全复用连接对象。但注意:Coroutine\MySQL 本身不提供连接池管理逻辑,它只是协程友好的 MySQL 客户端;你必须自己封装连接获取、归还、超时、最大连接数等行为。
实操建议:
- 用
Swoole\Coroutine\Channel实现连接队列,初始化时预创建 N 个Coroutine\MySQL实例并 push 进 channel - 获取连接时
$channel->pop($timeout),超时则抛异常或新建(需限制上限) - 使用完必须
$channel->push($conn)归还,否则连接泄漏;建议用defer确保执行 - 连接空闲超时(如 60 秒未被 pop)应主动
$conn->close(),避免服务端 kill 导致协程卡死
别直接用 swoole_mysql 扩展(已废弃)
旧版 swoole_mysql 扩展在 Swoole 4.4+ 中已被移除,现在统一走 Coroutine\MySQL。如果你看到文档里还在用 new swoole_mysql() 或配置 mysql.pool_size,说明资料过时。当前稳定路径只有:
- Swoole ≥ 4.8.0(推荐 ≥ 5.0)
- 启用
enable_coroutine = true(默认开启) - 所有数据库操作必须在协程内进行,不能混用同步阻塞调用
错误现象:ERROR swManager_loop: fatal error: fork() failed, Error: Resource temporarily unavailable —— 很可能是因为连接未归还 + 协程数爆涨,触发系统进程/文件描述符限制。
连接池不是万能的,小心慢查询拖垮整个池
一个慢查询会占用一个连接长达数秒,如果池大小是 10,10 个并发慢查询就能让后续所有请求在 channel 上等待超时。实际部署中必须:
- 为
pop()设置合理超时(如 100ms),超时后拒绝服务而非死等 - 对 SQL 执行加
max_execution_time(MySQL 5.7.8+ 支持)或用Coroutine::sleep()+kill配合实现软超时 - 监控
Channel->length()和Channel->capacity()差值,接近 0 时告警
最易忽略的一点:Swoole Worker 进程重启时,channel 中残留的连接对象不会自动 close,需监听 WorkerStop 事件手动遍历回收。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











