hyperf 3.1 已彻底弃用 worker_num,真实进程结构为1个master、1个manager、n个task worker;并发由task_worker_num(设为cpu核数×2~3)和max_coroutine(建议3000~10000)协同控制。

Hyperf 3.1 面试中常被问到“多进程模型怎么理解”“worker_num 还能配吗”,其实这两个问题背后指向同一个事实:Hyperf 3.1 已彻底弃用传统 Worker 进程概念,不再通过 worker_num 控制并发,而是依赖协程调度 + Task Worker 协同模型;答错这点,直接暴露对 Swoole 5+ 底层演进缺乏实操认知。
Hyperf 3.1 的真实进程结构长什么样
启动后实际存在的进程只有三类:【1个Master进程】、【1个Manager进程】、【N个Task Worker进程】——没有传统意义上的“Worker进程”。
Master 进程只做监听和分发,不跑业务代码;Manager 进程负责拉起/回收 Task Worker;所有 HTTP 请求、定时任务、RPC 调用,全部由协程在 Manager 管理的上下文中执行,而非分配给独立 Worker 进程。
所谓“多进程”,本质是 Task Worker 进程 + 协程调度器共同构成的混合模型,不是 Nginx 那种每个请求独占一个进程的模式。
为什么 server.settings.worker_num 配了也无效
Hyperf 3.1 基于 Swoole 5.x,默认使用 SWOOLE_PROCESS 模式,但已移除 worker_num 参数解析逻辑;配置文件里写 'worker_num' => 16,启动时完全忽略,日志里也不会警告。
如果你在 config/autoload/server.php 中还保留 worker_num 字段,它不会报错,但也不会生效——Swoole 5 的 Server 启动流程压根不读这个键。
强行保留该配置,只会误导新同学以为“调大就能抗更多并发”,结果压测时发现 QPS 上不去、CPU 却空转,根源就是没转向协程数与 task_worker_num 的协同调优。
真正该调的两个核心参数
方法一:task_worker_num —— 控制异步任务承载能力
① 先查物理 CPU 核数:lscpu | grep -E "Core|Socket" | awk '{print }' | paste -sd '*' - | bc
② 设为物理核数 × 2~3:例如 8 核机器,设 task_worker_num => 16~24;若任务含大量 I/O(如调外部 API、写 Kafka),取上限;若纯计算(如图像缩放),取下限。
③ 【必须同时开启 task_enable_coroutine => true】,否则 Task Worker 内无法使用协程客户端,遇到 curl 或 DB 查询就会阻塞整个进程。
方法二:max_coroutine —— 控制单个进程内协程并发上限
这个值决定每个 Task Worker 进程最多同时跑多少个协程;默认是 0(不限),但生产环境建议设为 3000~10000,避免协程过多导致内存暴涨或调度延迟。
设太高会导致单个 Task Worker 协程排队严重,响应变慢;设太低则协程频繁创建销毁,GC 压力大。验证方式:启动后访问 /status 接口,观察 coroutine_num 是否长期接近 max_coroutine。
怎么验证配置真的生效了
第一步:启动加 -vvv 参数,php bin/hyperf.php start -vvv,首行日志会明确打印 loaded task_worker_num: 16。
第二步:运行中执行 curl http://127.0.0.1:9501/status(需先在 server.php 开启 status 服务),返回 JSON 中的 task_worker_num 和 tasking_num 必须与配置一致,且 tasking_num 在高负载时应动态变化。
第三步:用 ps aux | grep hyperf 查进程数,结果应接近 1(Master)+ 1(Manager)+ N(Task Worker),若看到多个 “worker” 进程,说明你还在用 Hyperf 2.x 的旧配置或误启了兼容模式。











