FrankenPHP默认为普通模式,worker模式需在Caddyfile中显式配置并适配代码:使用worker-aware入口(如Symfony的public/worker.php),避免全局变量残留与超全局变量未重置问题。

不是开箱即用,需要显式启用并适配代码结构。
worker模式必须在Caddyfile中手动开启
FrankenPHP 默认运行在“普通模式”(per-request),和传统 PHP-FPM 行为一致;worker 模式不会自动激活。你得在 Caddyfile 的 PHP 路由块里明确写上 worker 指令:
localhost {
route {
php {
root /var/www/symfony
worker
}
}
}
漏掉这行,哪怕 Symfony 项目本身支持 worker,FrankenPHP 也只会每次新建 PHP 实例执行 index.php。
Symfony 应用需使用 worker-aware 入口文件
标准的 public/index.php 是为单次请求设计的,它会完整初始化 Kernel、容器、事件循环,然后退出。Worker 模式下这个流程必须只做一次,后续请求复用已初始化环境。因此你得:
立即学习“PHP免费学习笔记(深入)”;
- 改用
public/worker.php(Symfony 官方自 6.3+ 提供)或自定义入口 - 确保该入口调用
Kernel::boot()仅一次,并长期持有$kernel实例 - 避免在每次请求中重复调用
new Kernel()或$kernel->boot() - 注意:某些 Bundle(如 Doctrine Migrations、Monolog 文件处理器)在常驻内存下可能缓存失效或句柄泄漏,需检查其是否支持长生命周期
常见错误现象:HTTP 500 或请求卡死
没改入口却启用了 worker,典型表现是:
- 首次请求成功,后续请求返回
500 Internal Server Error,日志里出现Class 'App\Kernel' not found—— 因为 autoloader 在第一次请求后被重置或隔离 - 请求长时间无响应,
frankenphp_busy_threads持续为 1,frankenphp_queue_depth不断上涨 —— 入口卡在某处未正确 return 或 exit,导致线程无法回收 -
curl http://localhost:2019/metrics | grep frankenphp显示frankenphp_total_threads和frankenphp_busy_threads始终相等,说明所有线程都被占住,没有释放回池
性能提升不是线性的,取决于框架初始化占比
Worker 模式的价值集中在“抹掉框架启动开销”。对一个典型 Laravel/Symfony API 接口:
- 普通模式下,框架引导常占 40–80ms(含容器编译、配置加载、服务注册)
- Worker 模式下这部分被摊薄为 0,只剩业务逻辑 + DB 查询耗时
- 但如果你的接口本身要花 800ms 做同步 HTTP 调用或大文件处理,worker 带来的收益就微乎其微
- 别忘了:worker 进程共享内存,全局变量、静态属性、未清理的资源句柄(如 PDO 连接)会跨请求残留 —— 这既是优势也是雷区
最易被忽略的一点:worker 模式下,$_SERVER、$_GET、$_POST 等超全局变量不会自动重置,Symfony 的 Request 对象必须每次从当前请求上下文重建,不能缓存或复用旧实例。



















