根本原因是Workerman默认以前台模式运行,php start.php start启动后终端关闭即退出;必须加-d参数启用守护进程,且pidFile需设为可写绝对路径,否则静默失败。

php start.php start 启动后立即退出,根本原因是前台模式
Workerman 默认不 daemonize,php start.php start 启动的是前台进程,终端关闭或 SSH 断开,父进程收到 SIGHUP,整个进程树就结束了。这不是异常,是设计使然。
必须加 -d 参数才能 fork 出后台守护进程:php start.php start -d。但注意:它不会报错告诉你失败了——如果 $worker->pidFile 路径不可写、不是绝对路径、或目录不存在,-d 会静默失败,进程启动几秒后自动退出,看起来“刚启就挂”。
-
$worker->pidFile必须设为绝对路径,例如/var/run/workerman.pid,不能用workerman.pid这类相对路径 - 确保运行用户(如
www-data)对 pidFile 所在目录有写权限,mkdir -p /var/run && chown www-data:www-data /var/run - 别用
nohup php start.php start &—— Workerman 没处理 SIGHUP,子进程仍可能被中断
exit with status 256 是 PHP 崩溃,不是 Workerman 问题
看到日志里有 exit with status 256,基本等于 PHP 子进程发生了致命错误(如调用禁用函数、扩展段错误),内核强制终止,返回状态码 256(即信号 1 的等效值)。
最该先跑的命令是:curl -Ss http://www.workerman.net/check.php | php。它会明确指出哪些必需函数被 disable_functions 拦住了,比如 pcntl_fork、posix_kill —— 这两个一被禁,master 就无法管理 worker,必然闪退。
- 检查禁用函数:
php -i | grep disable_functions - 确认关键扩展已启用:
php -m | grep -E "pcntl|posix|sockets" - 临时开启全量错误输出:在
start.php开头加ini_set('display_errors', 'on'); error_reporting(E_ALL);,否则 fatal 错误完全不落地
Supervisor 下报 FATAL 或反复重启,其实是启动失败三次以上
Supervisor 日志里出现 gave up: workerman entered FATAL state, too many start retries too quickly,说明 Workerman 主进程连续三次启动都失败了(比如配置语法错、端口被占、权限不足),Supervisor 主动放弃,不是 Supervisor 故障。
关键点在于 Supervisor 的 command 必须带 -d,且不能漏掉 stopasgroup=true 和 killasgroup=true —— 否则 supervisorctl stop 只杀主进程,worker 子进程变僵尸,下次启动时端口被占,又失败,形成死循环。
-
command=/usr/bin/php /path/to/start.php start -d—— 缺-d就注定失败 - 务必设
user=www-data(和 PHP 实际运行用户一致),避免日志/ pid 写入失败 -
redirect_stderr=true+stdout_logfile=必开,否则 PHP warning/fatal 全丢进黑洞
Windows 下双击 workerman.bat 闪退,大概率是环境变量没配好
Windows 用户双击 workerman.bat 窗口一闪而过,90% 是系统找不到 php 命令。不是 Workerman 问题,是 PATH 没把 PHP 目录加进去。
打开 CMD,执行 php -v,如果提示“不是内部或外部命令”,就证实了这点。必须把 PHP 安装目录(如 C:\php)加到系统环境变量 PATH 中,再重新打开 CMD 验证。
- 别依赖 bat 文件里写死的 php 路径(如
"C:\php\php.exe"),容易因版本升级失效 - 确保用的是 CLI 版本的 PHP(
php -v输出含cli),而不是 Apache 或 Nginx 模块版 - PHP 版本至少 7.1+,低于此版本 Workerman 3.x 无法运行
-d,深层往往是权限、禁用函数、路径、环境变量这些“基础设施”没对齐。最容易被忽略的是:-d 失败不报错,disable_functions 拦了关键函数也不提示,它们共同制造了“莫名其妙就没了”的假象。

















