master进程挂则服务不可用,manager挂则worker变孤儿进程失管,worker崩溃影响最小——manager会立即拉起新进程;master仅运行reactor线程处理网络事件,不执行php业务代码,避免阻塞事件循环。

Master 进程挂了,整个服务就不可用了;Manager 挂了,Worker 会变成孤儿进程,不再受控;Worker 崩溃本身影响最小——Manager 会立刻拉起新进程。这是理解三者关系最硬的判断依据。
Master 进程为什么不能执行业务代码
它内部运行的是 Reactor 线程(基于 epoll / kqueue),只做连接监听、数据收发、协议解析和分发,不加载 PHP 用户代码。一旦在 onStart 或信号回调里写耗时逻辑(比如同步连 Redis、读大文件),就会卡住整个网络事件循环,导致新连接无法 Accept、已有连接响应延迟甚至超时断开。
常见错误现象:
-
ERROR swReactorThread_onRead: connection#1 closed, errno=0(大量连接被异常关闭) - 监控显示 CPU 很低但 QPS 断崖下跌
- 用
strace -p $MASTER_PID能看到线程长时间阻塞在epoll_wait外的系统调用上
正确做法是:所有业务逻辑必须放在 onReceive / onRequest 等 Worker 回调中;onStart 仅做配置初始化、创建 Swoole\Table 或 Swoole\Atomic 等共享结构。
Manager 进程崩溃后 Worker 会怎样
Manager 是 Worker 的“监护人”,它通过 waitpid 监控每个 Worker 子进程状态。一旦 Manager 进程退出(比如被 kill -9、或自身 C 扩展 bug 导致段错误),所有 Worker 进程会失去父进程,成为 init 进程(PID 1)的子进程,不再接受任何管理指令。
后果包括:
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- Worker 崩溃后不会自动重启,服务可用性逐步下降
-
kill -USR1 $MASTER_PID平滑重启失效(因为 Manager 不再响应信号) - 无法通过
swoole_server->reload()触发滚动更新 - 日志里出现
WARNING swManager_loop: worker#0 abnormal exit, status=0, signal=11后不再有后续恢复记录
所以生产环境务必避免直接杀 Manager;若需调试,优先用 gdb attach $MANAGER_PID,而非 kill。
worker_num 和 task_worker_num 配置不当的典型表现
这两个参数不是越大越好,它们直接影响内存占用、上下文切换开销和任务堆积风险。
worker_num 设置过高(如设为 64 核机器配 128):
- 每个 Worker 占用独立内存(含协程栈、PHP 全局变量副本),OOM 风险陡增
- Reactor 线程往过多 Worker 投递数据时,管道(
pipe)写入可能阻塞,引发WARNING swFactoryProcess_finish: send 1024 bytes to worker#0 failed, errno=32
task_worker_num 设置过低(如高并发邮件投递场景只配 2):
- Task 队列持续积压,
swoole_server->task()调用开始超时或返回false - Worker 在
taskwait时被阻塞,无法处理新请求,形成雪崩 - 监控发现
server->stats()['tasking_num']长期 > 80% 容量
建议值:worker_num 设为 CPU 核数 × 1~1.5;task_worker_num 按峰值异步任务 QPS × 平均处理时长估算,宁可略高勿低,并配合 task_max_request 防止内存泄漏累积。
真正容易被忽略的是:Reactor 线程和 Worker 进程之间靠 Unix Socket 通信,而 Manager 与 Worker 之间靠 waitpid + 信号协作——这两层 IPC 机制完全独立,出问题时排查方向也完全不同。别一看到 Worker 崩溃就只查业务代码,先确认 Manager 是否还在健康运行。










