systemd 和 supervisor 同时管理同一 frankenphp 实例会导致进程反复拉起、日志混乱、端口冲突和 socket 并发写入;根本原因是二者进程存活判断逻辑不同引发竞态,必须停用其一:生产环境优先用 systemd,开发调试可用 supervisor,严禁共存。

systemd 和 supervisor 同时管理同一个 FrankenPHP 实例会怎样
会出现进程反复拉起、日志混乱、端口冲突、socket 文件被并发写入等问题。典型现象是 journalctl -u frankenphp 里看到同一服务启动又退出,或 ps aux | grep frankenphp 显示多个 PID 指向相同脚本和端口。这不是 FrankenPHP 的 bug,而是两个管理器对“进程存活”判断逻辑不同导致的竞态:supervisor 认为进程挂了就重启,systemd 却认为它还在运行,结果两边都试图接管。
如何确认当前 FrankenPHP 进程由谁控制
先查进程本身:ps -o pid,ppid,comm,args -p $(pgrep -f "frankenphp.*worker")(Linux/macOS)或 tasklist /FI "IMAGENAME eq frankenphp.exe"(Windows)。重点看:
- PPID(父进程 ID)是否是
systemd或supervisord -
args列是否含--addr :8081等参数,且路径是否与配置文件一致 - 用
systemctl list-units --type=service | grep frankenphp查 systemd 是否已启用同名 service - 用
supervisorctl status查 supervisor 是否也启用了同名 program
如果两者都显示 active/running,说明确实在双管齐下。
必须停掉其中一个管理器
不能“协调共存”,FrankenPHP worker 进程不支持被多管理器同时 watch。选择依据很简单:
- 生产环境优先用
systemd:日志自动归档(journalctl)、资源限制(MemoryMax=)、开机自启、依赖管理成熟 - 开发调试阶段可用
supervisor:配置热重载快、supervisorctl reread+update响应及时、错误输出直接打屏 - 一旦选了 systemd,就删掉
/etc/supervisor/conf.d/frankenphp.conf并执行supervisorctl reread && supervisorctl update - 一旦选了 supervisor,就执行
sudo systemctl disable frankenphp.service && sudo systemctl stop frankenphp
别留着“备用”——残留的 service 文件哪怕没 enable,也可能被 systemctl daemon-reload 扫到并意外激活。
检查残留的 auto-start 配置
最容易被忽略的是 shell 初始化脚本或 IDE 配置偷偷启动 FrankenPHP:
- 检查
~/.bashrc、~/.zshrc、~/.profile是否有frankenphp worker --addr类命令 - IDE(如 PHPStorm)的 “Run Configurations” 里是否勾了 “After launch” 自动执行脚本
- Docker Compose 中是否同时定义了
command:启动 worker 和外部supervisord容器 - 某些 CI/CD 脚本(如 GitHub Actions 的
deploy.sh)可能在部署后手动nohup frankenphp worker &
这些地方不会出现在 systemctl 或 supervisorctl 列表里,但会真实抢走端口并干扰管理器判断。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











