Workerman 用 -d 参数启动后关终端即退出,因其仅后台化但未脱离会话,仍受 SIGHUP 影响;真正守护需配合 nohup 重定向或 systemd 管理,禁用 -d 并配置 Type=simple、Restart=always 等。

Workerman 用 -d 参数启动后为啥一关终端就退出?
因为 -d 只是让 Workerman 进入后台(daemonize),但没真正脱离终端会话控制。Linux 下子进程默认继承父进程的会话和控制终端,关掉 ssh 终端时,SIGHUP 信号会传给整个会话组,-d 启动的进程仍会被杀死。
实操建议:
-
-d必须配合--daemon(旧版)或确保配置中$worker->daemonize = true;生效,否则只是假后台 - 单纯加
-d不足以抗 SIGHUP,得用nohup或systemd管理会话生命周期 - 验证是否真后台:启动后立刻执行
ps aux | grep workerman,再断开 ssh,重新登录再查 —— 如果进程没了,说明没真正守护住
不用 systemd 时,nohup + -d 怎么写才可靠?
很多人写成 nohup php start.php start -d &,但漏掉了输出重定向,导致 nohup.out 暴涨,且 stderr 仍可能触发挂起。
实操建议:
- 必须显式重定向 stdout 和 stderr:
nohup php start.php start -d > /dev/null 2>&1 & - 启动前先
cd到项目根目录,避免相对路径加载失败(比如autoload.php找不到) - 别依赖当前 shell 的环境变量,如需
PATH或自定义变量,用env显式带入:env PATH=/usr/local/bin:$PATH nohup php ...
systemd 管理 Workerman 时,-d 要不要加?
不要加。systemd 本身就是进程管理器,自己负责 fork、重定向、重启策略。Workerman 在 systemd 下运行时若还加 -d,会导致双重 daemonize,常表现为进程异常退出、日志写不进 journalctl、systemctl status 显示 inactive。
实操建议:
- service 文件里
ExecStart=php /path/to/start.php start—— 去掉-d - 设
Type=simple(不是 forking),因为 Workerman 主进程不 double-fork - 加
Restart=always和RestartSec=3,比靠-d自恢复更可控 - 务必配
WorkingDirectory,否则相对路径配置(如日志文件)容易失效
怎么确认 Workerman 真正被守护住了?
光看进程存在不够。守护成功的核心指标是:不受终端生命周期影响、崩溃后能自动拉起、日志可追溯、端口持续监听。
实操建议:
- 用
lsof -i :2345(替换成你的监听端口)确认端口始终被同一 PID 占用 - 查日志:
systemctl journalctl -u your-workerman.service -n 20(systemd)或翻workerman.log最后时间戳是否连续 - 手动 kill 主进程(不是子进程):如果 3 秒内自动复活,说明守护逻辑生效;如果没反应,检查
restart配置或权限(比如www-data用户无权读取某些配置文件) - 注意 Workerman 子进程(Worker 进程)本身不响应
kill -9,但主进程挂了整个服务就停 —— 守护对象永远是主进程,不是子进程
nohup,就得自己管好重定向和会话;交给 systemd,就得让它全权接管,别再让 Workerman 自己 fork。这点最容易被忽略,一错就是服务隔两天就掉线。










