Workerman执行start命令无反应或直接退出,本质是master启动后因Fatal Error导致worker进程未创建;需检查autoload路径、PHP语法、ZTS模式、pcntl/sockets扩展、禁用函数、监听地址及端口权限。

start命令执行后无反应或直接退出
Workerman 的 php start.php start 命令看似执行成功,但实际没监听端口、ps aux | grep WorkerMan 看不到 worker 进程,本质是主进程启动后因异常快速退出,systemd 或 shell 都来不及捕获日志。这不是“命令无效”,而是启动流程在 onWorkerStart 或更早阶段就 fatal error 了。
立刻检查以下几处:
- 打开
start.php,确认require_once __DIR__ . '/vendor/autoload.php';在最前,且路径正确(vendor目录存在、autoload.php可读) - 运行
php -l start.php检查语法错误;再用php start.php start -d=false强制前台运行,看控制台是否输出Fatal error或Parse error - 若报
Class 'Workerman\Worker' not found,说明workerman/workerman未被 autoload 加载——检查composer.json中"autoload"是否漏配,或手动加require_once __DIR__.'/vendor/workerman/Worker.php'; - Windows 下未加
-d参数却用了--daemon=1,会导致 fork 失败后静默退出;必须用php start.php start -d(仅 Windows)
执行 start 后提示 “Start success” 但 ss -tuln 查不到监听
“Start success” 只表示 master 进程起来了,不代表 worker 子进程已就绪。真正提供服务的是 worker 进程,它由 master fork 出来,而 fork 失败时 master 不报错也不退出,只是不拉起 worker。
重点排查:
-
php -i | grep "thread safety"输出enabled?ZTS 模式会令pcntl_fork()静默失败,必须换用 NTS 版 PHP -
php -m | grep pcntl和php -m | grep sockets必须都有输出;任一缺失,worker 就无法创建 -
php -i | grep disable_functions确认pcntl_fork、stream_socket_server不在禁用列表里 - 检查
start.php中new Worker('tcp://0.0.0.0:2345')的地址写法——若写成127.0.0.1或本机公网 IP(如腾讯云非绑定 IP),ss -tuln会显示127.0.0.1:2345而非*:2345,外部连接必然失败
start 命令报错 “Address already in use” 或 “Permission denied”
这两类错误都发生在 stream_socket_server() 调用时,属于系统级拒绝,Workerman 无法绕过。
对应处理方式很明确:
-
Address already in use:不是端口“被占用”,而是上一次 Workerman 没正常 stop,残留了 socket。先跑killall php或ps aux | grep Worker | awk '{print $2}' | xargs kill -9,再ss -tuln | grep :2345确认清空,最后php start.php start -
Permission denied:分两种情况:
– 端口号 ≤ 1024(如 80、443),Linux 要求 root 权限,开发阶段请改用8080等高位端口;
– 绑定地址写错,比如填了云服务器的公网 IP(实际不属于该机器),必须统一用0.0.0.0 - 如果是 Docker 容器内启动,除了
-p 2345:2345,容器内Worker构造函数也必须是'tcp://0.0.0.0:2345',不能是127.0.0.1
systemd 下 start 命令始终 inactive (dead)
在 systemd 里执行 php start.php start 却看不到进程,几乎全是配置误用导致的。systemd 不是 shell,它对进程模型有硬性要求。
必须核对三项:
-
ExecStart命令末尾**不能带-d或--daemon=1**,必须用--daemon=0(v5+)或start -d=false(v4),否则主进程 fork 后 exit,systemd 认为启动失败 -
Type=必须是simple,绝不能写forking;Workerman 不符合传统 daemon 的父子进程分离模型 -
User=必须是非 root 用户(如www-data),否则bind()会因权限被拒;同时确保该用户对项目目录有读写权限(尤其是runtime/和日志路径)
验证时别反复 start/stop,先跑 sudo journalctl -u your-service-name -f 实时盯住输出,90% 的问题日志里第一行就写了原因。

















