Master进程只监听端口、运行Reactor事件循环、转发信号;Manager进程才真正fork、监控、回收并重启Worker/Task进程,是Swoole多进程模型中负责子进程生命周期管理的“守夜人”。

Master进程不负责管理子进程生命周期,Manager进程才是真正的“进程守夜人”——这是最常被混淆、也最容易在 reload 或崩溃恢复时踩坑的地方。
Master进程只干三件事:监听端口、运行Reactor线程、转发信号
它本质是个多线程进程,主线程是 MainReactor,其余是 Reactor 子线程,全部跑在 epoll/kqueue 事件循环里。它不 fork 任何业务进程,也不回收死掉的子进程。你看到的 ps aux | grep swoole 里第一个进程就是它,但它的职责仅限于:
• 监听 TCP/UDP 端口并接受新连接
• 把连接分发给某个 Reactor 线程处理收发数据
• 收到 SIGTERM、SIGUSR1 这类信号后,原样转发给 Manager 进程(不是自己处理)
Manager进程才是真正 fork 和回收 worker/task 的那个
所有 worker_num 和 task_worker_num 配置生成的进程,都是由 Manager 进程 fork() 出来的。它不碰网络 IO,也不执行 PHP 代码,只做四件事:
• 启动时批量 fork 出指定数量的 Worker 和 TaskWorker 进程
• 监听子进程退出信号(SIGCHLD),立即回收僵尸进程
• 某个 Worker 因段错误或 exit() 崩溃后,自动拉起一个新进程补位
• 执行 reload 时,逐个 kill + restart Worker 进程,保证服务不中断
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
为什么不能跳过 Manager 直接让 Master fork?
因为 Master 是多线程的,而 fork() 在多线程进程中是危险操作:子进程只会复制调用 fork() 的那个线程,其他 Reactor 线程状态丢失,极易导致 epoll 实例损坏或内存不一致。Swoole 强制用单线程的 Manager 来承担 fork 职责,就是为了规避这个 POSIX 层面的陷阱。如果你在 onStart 回调里手动 pcntl_fork(),大概率会触发 epoll_ctl: Bad file descriptor 或连接突然断开。
怎么确认 Manager 进程是否正常工作?
看日志和进程树是最直接的方式:
• 启动后执行 ps -ef | grep your_swoole_app,应该能看到至少 3 类 PID:Master(最老)、Manager(次老)、若干 Worker/TaskWorker(最新)
• 在 onWorkerError 回调里打日志,如果进程崩溃后你看到新 PID 的 Worker 被拉起,说明 Manager 在干活
• 故意在 Worker 中写 exit(1),观察 Manager 日志是否输出 "worker exit, restart" 类似信息
• 关键点:Manager 进程本身没有 PHP 回调,你无法在它里面写逻辑;它纯 C 实现,只响应系统信号和子进程事件
真正容易被忽略的是:Manager 进程一旦异常退出(比如被 kill -9),整个 Swoole 服务就失去自愈能力——后续所有 Worker 崩溃都不会被重建,只剩 Master 和残存 Worker 挣扎运行。所以生产环境必须用 supervisor 或 systemd 看护 Manager 进程本身,而不是只看护启动脚本。

















