frankenphp worker模式下pdo连接被进程复用,需显式启用持久连接(pdo::attr_persistent => true)、禁用自动关闭、合理配置max_connections并严格管理事务与资源释放。

数据库连接在 FrankenPHP 下会复用,不是每次请求新建
Worker 模式启用后,PDO 实例不再随请求销毁,而是被整个 Worker 进程复用。这意味着:连接不会自动关闭、事务不会自动回滚、prepare 语句可能跨请求污染。如果你沿用 ThinkPHP/Laravel 默认的“每次请求 new PDO”写法,很快就会触发 MySQL server has gone away 或连接数打满。
- 必须显式配置 PDO 的持久连接:
pdo::ATTR_PERSISTENT => true(ThinkPHP 在config/database.php中设'persistent' => true;Laravel 在.env加DB_PERSISTENT=true) - 禁用框架自动关闭连接行为:Laravel 要确认
doctrine.dbal.auto_close为false(某些旧版 Bundle 会覆盖该值) - 避免在循环或高频逻辑中调用
DB::connection()->getPdo()后不unset—— 这类手动取连接的操作必须配对释放 - 检查是否用了
new PDO(...)原生写法:若存在,必须包裹在try/finally中,确保$pdo = null或unset($pdo)
MySQL max_connections 必须按 num_threads × 连接池大小反推
FrankenPHP 的 num_threads 不是并发请求数上限,而是常驻 PHP 线程数;每个线程默认复用 1~5 个 PDO 连接(取决于框架连接池配置)。若 num_threads = 8、每个线程最多持 5 个连接,则 MySQL 至少要设 max_connections = 48,否则会出现 Too many connections 错误,且错误日志里看不到明显堆积迹象——连接是静默耗尽的。
- 用
netstat -an | grep :3306 | wc -l持续观察连接数趋势,缓慢上涨就是泄漏信号 - 不要依赖
wait_timeout自动回收:Worker 进程长期存活,连接空闲超时机制基本失效 - 在
my.cnf中显式设置:max_connections = 64(起步值),再根据压测结果上调 - 如果应用用了 Doctrine Proxy 类或大量 classmap autoload,实际连接开销可能比理论值高 20%~30%
runtime 目录权限和缓存路径必须可写,但不能暴露给 Web
runtime/(ThinkPHP)、var/cache/(Symfony)、storage/framework/(Laravel)这些目录在 Worker 模式下会被多个线程同时读写。Linux 下仅设 chmod -R 755 runtime 不够安全,也容易因 umask 导致子目录权限异常。
- 推荐用
chown -R www-data:www-data runtime+chmod -R 775 runtime(假设运行用户是www-data) - 确保 Caddy 的
php_server块未将runtime/映射为 Web 可访问路径,否则可能泄露缓存文件或 session 内容 - 缓存驱动尽量避开
file:改用redis或memcached,避免多线程写同一文件引发锁竞争或损坏 - 如果必须用文件缓存,确认框架已启用原子写入(如 ThinkPHP 的
'atomic' => true)
连接泄漏比性能瓶颈更早拖垮服务
Worker 进程常驻后,curl_init()、new PDO()、fopen() 这些资源型操作一旦没显式释放,就会持续累积。现象不是 CPU 飙高,而是请求卡在 fopen 系统调用上,ulimit -n 耗尽后连错误日志都写不出。
- 所有资源型操作必须有明确的 close/destroy/unset 路径,不能依赖析构函数
- 日志写入禁用
StreamHandler,改用RotatingFileHandler并设max_files: 7 - 检查
public/worker.php入口是否在frankenphp_handle_request()外层做了register_shutdown_function()清理,但别在里面做耗时操作(如 DB rollback) - 最隐蔽的泄漏点:ORM 查询构造器本身不持有连接,但
DB::transaction()块外没commit或rollback,会导致连接一直挂在事务状态
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











