FrankenPHP 启动多个 worker 时需分别运行独立实例,每个通过 --script 指定唯一绝对路径的 PHP 脚本(如 /var/www/queue.php),并用 --addr 绑定不同端口(如 :8081 和 :8082),再由 supervisor 或 systemd 统一管理生命周期。

FrankenPHP 启动多个 worker 时如何指定不同 PHP 脚本
FrankenPHP 的 worker 模式默认只支持一个入口脚本(worker.php),不能直接通过配置让两个 worker 进程分别跑 queue.php 和 notify.php —— 它不是进程管理器,不提供多脚本并行 worker 的原生抽象。
用 supervisor 或 systemd 管理多个 FrankenPHP worker 实例
真正可行的做法是启动多个独立的 FrankenPHP worker 进程,每个绑定自己的脚本和监听端口(或 Unix socket),再由外部进程管理器维持生命周期。常见错误是试图在单个 frankenphp-worker 命令里传入多个 --script,这会报错:unknown flag: --script(该命令不接受重复或多个脚本参数)。
- 每个 worker 实例必须单独执行一条
frankenphp-worker命令,且各自指定--script和--addr -
--addr必须互不冲突(例如:8081和:8082),否则第二个会因端口被占而退出 - 推荐用
supervisord或 systemd service 分别定义[program:worker-queue]和[program:worker-notify],避免手动维护 - 注意:FrankenPHP 的 worker 模式不共享内存或事件循环,两个脚本完全隔离,无法直接通信
worker.php 内部做路由分发(不推荐但可行)
如果硬要“一个 worker 进程跑两个逻辑”,可以在 worker.php 里根据环境变量或配置启动不同子任务,比如用 pcntl_fork() 派生子进程。但这绕过了 FrankenPHP 的设计初衷,容易引发信号处理异常、内存泄漏或 SIGCHLD 积压问题。
- FrankenPHP 的 worker 已接管主事件循环,自行 fork + loop 容易与内置 reactor 冲突
-
pcntl在某些容器环境(如 Alpine + musl)可能不可用或行为异常 - 日志、错误捕获、优雅退出需全部手动实现,调试成本远高于起两个独立 worker
- 示例中看似简洁的
if ($_ENV['WORKER_TYPE'] === 'queue') { ... }实际上线后难以监控和扩缩容
关键细节:--script 路径必须为绝对路径
FrankenPHP 对 --script 参数校验严格,相对路径(如 --script=queue.php)会导致 failed to open stream: No such file or directory 错误,即使当前目录正确 —— 因为 worker 进程启动后工作目录可能已切换。
立即学习“PHP免费学习笔记(深入)”;
- 务必使用
--script=/var/www/queue.php这类绝对路径 - 建议在 supervisor 配置中用
directory=/var/www并显式写全路径,避免歧义 - 检查脚本权限:FrankenPHP worker 进程以运行用户身份执行,需确保该用户对脚本有读+执行权限(
.php文件本身不需要 +x,但需可读)
worker.php 里加 if-else,也别指望一个 frankenphp-worker 命令启动多个逻辑流——把复杂性交给 supervisor、systemd 或 k8s,才是稳定运行的关键。



















