FrankenPHP 不支持为不同应用分配 Worker,需通过 systemd 或 supervisor 启动多个独立实例,每个绑定唯一端口和绝对路径脚本,彼此隔离无共享状态。

FrankenPHP 不能“为不同应用分配 Worker”
FrankenPHP 本身不提供跨应用的 Worker 调度或隔离能力。它的 worker 模式只支持单个 PHP 脚本常驻执行,每个 worker 进程绑定且仅运行一个 --script(必须是绝对路径)。所谓“不同应用”,实际意味着你要启动多个独立的 FrankenPHP worker 实例,各自加载自己的入口脚本。
用 systemd 或 supervisor 启动多个独立 worker 实例
这是唯一可靠、生产可用的方式。每个实例彼此隔离,无共享状态,也互不影响。
- 每个实例必须使用不同的
--addr(如:8081、:8082),否则端口冲突导致第二个直接退出 -
--script必须是绝对路径,例如--script=/var/www/app1/worker.php和--script=/var/www/app2/worker.php;相对路径会报failed to open stream: No such file or directory - 不要尝试在一条命令里传多个
--script:命令行解析器会报错unknown flag: --script - 推荐用 systemd service 文件分别定义
frankenphp-app1.service和frankenphp-app2.service,便于启停、日志分离和资源限制
Caddyfile 中无法“按域名分发到不同 worker”
FrankenPHP 的 php_server 指令作用于 HTTP 请求路由层,而 worker 模式是后台常驻进程,两者不在同一抽象层级。Caddy 不会、也不能把某个域名的请求“转发给指定 worker 进程”——worker 是独立于 HTTP 流量的后台任务(如队列监听、通知推送),不是 Web handler。
- 如果你希望不同域名走不同 PHP 应用,应该用
php指令配合root+try_files,指向各自index.php,由 FrankenPHP 的 PHP 线程池统一执行 - 如果你需要两个后台任务(比如一个处理队列、一个发邮件),就必须起两个 worker 实例,并用外部工具(如 supervisor)管理它们的生命周期
- 试图在
worker.php内部靠$_ENV或配置做“多租户路由”,会破坏进程隔离性,导致内存泄漏、信号处理异常,且无法横向扩缩容
容易忽略的关键细节
worker 实例之间完全不通信,也没有内置协调机制。这意味着:
立即学习“PHP免费学习笔记(深入)”;
- 你无法让 app1 的 worker 直接触发 app2 的逻辑——得通过 Redis、数据库或 HTTP API 显式调用
- 每个 worker 的日志需单独配置输出路径,否则混在一起难以排查
- 内存限制(
memory_limit)是按进程生效的,两个 worker 就占双份,务必检查num_threads × memory_limit < available_memory - Docker 环境下,别依赖当前工作目录;用
WORKDIR明确设置,并在--script中写死绝对路径



















