frankenphp 不支持为不同站点配置独立 worker,必须通过 systemd 或 supervisor 启动多个隔离实例,每个绑定唯一端口和绝对路径脚本,彼此无共享状态。

FrankenPHP 本身不支持“为不同站点配置独立 Worker”
FrankenPHP 的 worker 模式只作用于单个 PHP 脚本,每个 worker 进程绑定且仅运行一个 --script(必须是绝对路径)。它不是进程管理器,也没有内置的多租户或按域名路由 worker 的能力。所谓“给不同站点配独立 Worker”,实际意味着你要启动多个完全隔离的 FrankenPHP worker 实例,各自加载自己的入口脚本。
必须用 systemd 或 supervisor 启动多个独立实例
这是唯一生产可用的方式。每个实例彼此无共享状态,互不影响:
- 每个实例需指定唯一
--addr(如:8081、:8082),端口冲突会导致后续实例直接退出 -
--script必须是绝对路径,例如--script=/var/www/site-a/worker.php和--script=/var/www/site-b/worker.php;相对路径会报failed to open stream: No such file or directory - 不能在一条命令里传多个
--script:命令行解析器会报unknown flag: --script - 推荐为每个站点定义单独的 systemd service 文件,如
frankenphp-site-a.service,便于日志分离、启停控制和内存限制
Caddyfile 里不能靠域名把请求“转发给某个 worker”
php_server 指令处理的是 HTTP 请求,而 worker 是后台常驻任务(如队列监听、定时推送),两者不在同一层级。Caddy 不会、也不能把 site-a.com 的请求路由到某个特定 worker 进程。
如果你只是想让不同域名跑不同 Web 应用(比如 Laravel + ThinkPHP),正确做法是:
- 在 Caddyfile 中用多个
server块,分别匹配域名 - 每个块内用
root指向对应项目的public/目录 - 用
php指令(非worker)配合try_files,由 FrankenPHP 的 PHP 线程池统一执行index.php - 只有当你需要后台长期运行逻辑(如消费 Redis 队列、轮询 API),才真正需要独立 worker 实例
worker 实例之间无法直接通信,必须显式解耦
两个 worker 进程完全隔离,没有内置协调机制。这意味着:
- 你不能让
site-a的 worker 直接触发site-b的业务逻辑——得通过 Redis、数据库或 HTTP API 显式调用 - 每个 worker 的日志必须单独配置输出路径(如
error_log /var/log/frankenphp/site-a-worker.log),否则混在一起难以排查 - 内存限制是按进程生效的:
memory_limit = 256M× 2 个 worker = 至少 512M 实际占用,务必确认num_threads × memory_limit - Docker 环境下别依赖当前工作目录;用
WORKDIR明确设置,并在--script中写死绝对路径
最容易被忽略的一点:worker 脚本一旦启动,就脱离了 HTTP 生命周期,它的错误不会出现在 Web 日志里,也不会触发 Caddy 的健康检查。必须在脚本内手动捕获异常、记录日志、并确保 $worker->wait() 循环不中断——否则进程静默退出,你可能几天后才发现队列积压了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











