frankenphp 1.3 worker 模式需显式配置持久连接、框架适配与mysql调优才能启用数据库连接池;默认无池,易致连接泄漏、事务残留及“server has gone away”错误。

FrankenPHP 1.3 的 Worker 模式下,数据库连接池不是“开箱即用”的功能,而是需要显式配置+框架适配+MySQL协同调整才能真正生效。默认不设池,所有 PDO 实例都会被 Worker 进程长期持有,极易导致连接泄漏、事务残留、server has gone away 等问题。
必须启用 PDO 持久连接
Worker 模式复用的是整个 PHP 进程(含 PDO 对象),而非每次请求新建连接。若不开启持久化,连接会在某次请求结束后被意外关闭,下次复用时直接报错。
- ThinkPHP:在
config/database.php中设'persistent' => true - Laravel:在
.env中添加DB_PERSISTENT=true,并确认doctrine.dbal.auto_close=false(某些旧版 Bundle 会覆盖该值) - 原生 PDO:必须显式传入
[PDO::ATTR_PERSISTENT => true],且避免裸写new PDO()—— 若存在,务必包裹在try/finally中,手动置空或unset($pdo)
合理设置 MySQL max_connections
连接池大小 ≠ 框架里写的 pool_size: 16。实际连接数由 FrankenPHP 线程数 × 每线程最大连接数决定,而这个“每线程连接数”取决于框架连接池行为和代码是否释放资源。
- 假设
num_threads = 8,每个 Worker 线程平均持 4~5 个活跃连接,则 MySQL 至少要设max_connections = 48 - 低于该值不会立刻报错,而是静默耗尽——
netstat -an | grep :3306 | wc -l可观察连接数缓慢上涨,就是泄漏信号 - 建议留 20% 余量,例如预估需 48,实际设为 60
配置连接池超时与限流参数
光设池大小没用,必须配套超时机制,否则空闲连接长期滞留,MySQL 端已断开但 PHP 还以为连着,最终引发查询失败或卡死。
-
connection-timeout: 3000(毫秒):防止线程无限等待可用连接 -
idle-timeout: 60000(毫秒):空闲 60 秒自动回收连接,避免僵死连接堆积 - 部分框架(如 Laravel Octane 风格适配)需额外配置
pool_timeout和max_idle_time,确保与底层 PDO 行为一致
严格管理事务与资源生命周期
传统请求模型中,框架会在请求结束时自动 commit/rollback 并关闭连接;Worker 模式下这些动作不会自动触发,全靠代码显式控制。
- 任何手动调用
DB::connection()->getPdo()后,必须配对执行unset()或将变量置为null - 避免在循环内创建连接或 prepare 语句,prepare 跨请求可能污染绑定参数
- 事务必须显式
commit()或rollback(),不可依赖“请求结束自动回滚” - 使用 DB 监听器或中间件,在请求开始前清理上一个请求遗留的连接状态(如重置
PDO::ATTR_EMULATE_PREPARES)
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











