webman不能靠supervisor实现代码变更自动reload,仅能兜底防崩溃;fatal/starting因未加-d、权限不足、日志未配置或directory缺失导致;最小配置需command含-d、显式directory、stopasgroup=true等。

Webman 不能靠 Supervisor 实现“代码变更自动 reload”,但能靠它兜底防崩溃——只要主进程彻底退出,Supervisor 就会拉起新实例。
为什么 supervisorctl status 显示 FATAL 或 STARTING 卡住?
这不是 Supervisor 故障,而是 Webman 启动失败了。常见原因有:
-
command没加-d:Webman 默认前台运行,启动完立刻退出,Supervisor 认为“进程死了”,反复重试直到触发startretries上限,报gave up: xxx entered FATAL state - PHP 路径错误或权限不足:比如用
php命令但系统 PATH 里没配,或user=www-data对start.php所在目录无读取权限 - Webman 自身启动报错被吞:没开
stdout_logfile和stderr_logfile,所有错误都丢进黑洞,只能翻/var/log/supervisor/supervisord.log - 未设
directory:导致start.php里相对路径加载配置失败(如config_path())
Webman + Supervisor 的最小可行配置长什么样?
必须满足三个前提:Webman 进程前台不退出、日志可查、用户权限干净。以下是最简有效配置(存为 /etc/supervisor/conf.d/webman.conf):
[program:webman-api] command=/usr/bin/php start.php start -d directory=/home/www/website/api.webman.tinywan.com user=www-data autostart=true autorestart=true startsecs=5 startretries=3 redirect_stderr=true stdout_logfile=/var/log/webman/out.log stderr_logfile=/var/log/webman/err.log stdout_logfile_maxbytes=10MB stderr_logfile_maxbytes=10MB stopasgroup=true killasgroup=true
关键点说明:
-
command必须含-d:让 Webman 进入守护模式,主进程持续运行 -
directory必须显式指定:否则start.php内部的app_path()等函数可能定位错目录 -
stopasgroup=true+killasgroup=true:Webman 启动后会 fork 出 Monitor 进程和多个 Http 子进程,不加这两项,supervisorctl stop只杀主进程,子进程变僵尸 -
autorestart=true是“崩溃重启”,不是“热更新”——它只响应 exit code ≠ 0 或信号终止,对 Webman 内部的SIGUSR1reload 完全无感
Webman 的 Monitor 进程和 Supervisor 是什么关系?
完全不重叠,各干各的:
- Webman 的
Monitor进程(app/process/Monitor.php)负责监听文件变更、内存超限等应用层事件,并向自身 Http 进程发SIGINT触发优雅重启——这个过程主进程 PID 不变,Supervisor 根本察觉不到 - Supervisor 只盯着主进程的存活状态(PID 是否还在、是否异常退出),它不管 Webman 内部怎么 reload、怎么 fork、怎么回收内存
- 两者是互补关系:Monitor 处理“该不该 reload”,Supervisor 处理“挂了还能不能活”。别指望 Supervisor 替代 Monitor 的文件监控能力
如何验证 Supervisor 真正在管 Webman?
别只看 status,要主动制造一次崩溃再观察:
- 手动 kill 主进程:
kill -9 $(pgrep -f "php start.php start -d"),几秒后supervisorctl status应显示RUNNING(不是STARTING),且stdout_logfile里有新启动日志 - 检查子进程是否干净:
ps auxf | grep webman,确认只有 Webman 自己 fork 的子进程,没有残留的旧 worker 或孤儿进程 - 故意让 Webman 启动失败:比如注释掉
start.php里第一行#!/usr/bin/env php,然后supervisorctl restart webman-api,立刻去err.log查 PHP Fatal 错误,而不是在 supervisord.log 里盲找
真正容易被忽略的是:Supervisor 的 autorestart 和 Webman 的 Monitor 都依赖进程“干净退出”。如果 Webman 因段错误(segfault)或 OOM 被系统 kill,它可能来不及清理子进程,这时 stopasgroup=true 就成了保命线——否则下次启动会因端口占用或共享内存冲突直接失败。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











