每个frankenphp-worker实例必须用互不相同的--addr(如:8081、:8082),避免端口冲突导致启动失败;推荐使用四位数以上端口段,明确绑定回环地址(如127.0.0.1:8081)以提升安全性与可维护性。

frankenphp-worker 启动多个实例时 --addr 怎么设才不冲突
每个 frankenphp-worker 实例必须用 --addr 指定唯一监听地址,否则第二个会因端口被占直接退出。这不是“配置没生效”,而是操作系统级的 bind 失败。
常见错误是复用默认端口(比如都用 :8080)或只改端口号却忽略协议前缀导致语义混淆。
-
--addr :8080和--addr 127.0.0.1:8080在大多数场景下等效,但后者更明确绑定到回环接口,适合本地调试 -
--addr :8080和--addr :8081是安全的;--addr :8080和--addr 0.0.0.0:8080会冲突——它们监听的是同一端口的不同地址族,Linux 默认不允许重复 bind - 避免使用
:80、:443、:3000、:8000这类常见端口,除非你确定宿主机上没其他服务(如 Nginx、Caddy、开发服务器)在用 - 推荐用四位数以上端口段,例如
:8081、:8082、:8090、:8091,既避开常用工具默认值,又方便识别用途
怎么查端口是否真被占(尤其 macOS / Windows)
报错 “address already in use” 不等于“别人在用”,也可能是上一个 frankenphp-worker 没彻底退出,或者系统服务(如 Windows 的 HTTP.sys)霸占了 80/443。
不同系统查法差异大,错用命令会漏掉关键进程:
立即学习“PHP免费学习笔记(深入)”;
- macOS 必须用
lsof -P -n -i :8080,netstat不带 PID 字段,光netstat -an | grep LISTEN看不到谁在监听 - Windows 必须以管理员身份运行 CMD/PowerShell:
netstat -ano | findstr :8080→ 得到 PID →tasklist | findstr "1234";若 PID=4,别杀,那是 HTTP.sys,得停W3SVC或Web Deployment Agent Service - 查完发现是 FrankenPHP 自己残留:用
ps -p PID -o args=(macOS/Linux)或tasklist /fi "pid eq 1234"(Windows)确认命令行含frankenphp-worker和--addr,再 kill
systemd 或 supervisor 里怎么写才不会端口撞车
靠人工记端口号容易出错,尤其加新 worker 时。真正防冲突的做法是把端口作为 service 名的一部分,并在 unit 文件里显式声明。
例如 supervisor 配置中,不要只写 [program:worker],而要拆成:
[program:worker-queue] command=frankenphp-worker --script=/var/www/queue.php --addr=:8081 autostart=true autorestart=true [program:worker-notify] command=frankenphp-worker --script=/var/www/notify.php --addr=:8082 autostart=true autorestart=true
这样一眼能看出端口分配,且启动失败日志里会明确提示 listen tcp :8082: bind: address already in use,而不是笼统报错。
- systemd 同理:每个 service 文件名带端口,如
frankenphp-worker@8081.service,并在ExecStart=中硬编码--addr=:8081 - 禁止在同一个 service 里尝试启动两个
frankenphp-worker进程——它不是多 worker 管理器,--script参数不支持多次传入,会报unknown flag: --script - 如果要用变量化管理(比如统一改端口),建议用模板 + env 文件,而不是依赖 shell 替换,否则 reload 后可能漏 reload env
容器环境里 containerPort 和 --addr 要不要对齐
要,而且必须严格对齐。Kubernetes 的 containerPort 是声明式契约,不是“建议监听端口”。如果你在 frankenphp-worker 里用 --addr=:8081,但 Pod spec 里写的是 containerPort: 8080,那么 Service 的 targetPort: 8080 就转发不到真实进程。
更隐蔽的问题是:Caddyfile 或 SERVER_NAME 可能隐式影响监听行为。比如 SERVER_NAME=:80 会让 FrankenPHP 内置服务器监听 :80,此时即使你 --addr=:8081,它也可能忽略。
- 优先以
--addr为准:它是frankenphp-worker命令行的最终控制参数,覆盖所有环境变量和 Caddyfile 配置 -
containerPort值必须等于--addr中的端口号(不含协议和 IP),否则流量进不来 - 若用
--addr unix:///tmp/franken.sock,则containerPort不适用,需改用 hostPath volume + socket 文件挂载方式通信
lsof -i :端口 或 netstat -ano | findstr :端口 确认,比重启十次更省时间。**



















