$worker->count须在worker::runall()前设置且仅linux/macos有效;内存决定上限,io密集型建议cpu核数×3–5,cpu密集型设为核数或+1,混用场景需实测rss与%cpu动态调优。

Workerman 的 $worker->count 不是设得越高越好,也不是简单乘个 2 就完事——它直接受限于内存、业务类型和内核参数,设错会 OOM 或空转。
怎么设置 $worker->count 才生效?
必须在 Worker::runAll() 调用前赋值,且仅 Linux/macOS 有效(Windows 不支持多进程)。常见错误是把 $worker->count = 8 写在 onWorkerStart 里,那完全没用。
- 正确位置:Worker 实例创建后、
Worker::runAll()前 - 典型写法:
$worker = new Worker('http://0.0.0.0:8080'); $worker->count = 4; - 多个 Worker 实例要各自设,不能共用一个
count
$worker->count 设多少才不爆内存?
每个 Worker 进程常驻 RSS 内存约 30–60MB,取决于加载的类库、日志级别、中间件数量。别信“空进程才 5MB”这种说法——实测为准。
- 快速估算公式:
最大安全 count ≈ (总内存 MB) ÷ 单进程 RSS(MB) × 0.8 - 例如:16GB 内存服务器,实测单 Worker RSS 为 48MB →
16 × 1024 ÷ 48 × 0.8 ≈ 273,那就别超 270 - 压测时用
ps aux --sort=-%mem | grep php看真实 RSS,不是memory_get_usage()
不同业务类型对应的 count 推荐值
CPU 密集型和 IO 密集型的合理范围差一倍以上,混用场景更得靠实测判断倾向。
- CPU 密集型(如图像处理、大量计算、协程异步 MySQL/Redis):
count = CPU 物理核心数或+1 - IO 密集型(如同步
mysqli查询、file_get_contents、频繁 HTTP 调用):count = CPU 核数 × 3 ~ 5(4 核建议从 12 起压) - 混合型:先设
CPU 核数 × 2,再看top里各 PHP 进程的%CPU持续值 —— 若普遍低于 30%,说明 IO 等待多,可加;若长期 > 80% 且Recv-Q在ss -lnt中堆积,说明 CPU 已饱和,加也没用
为什么开了 $worker->reusePort = true 后 count 可以更小?
启用 reusePort 后,内核直接把新连接分发给空闲 Worker 进程,避免主进程 accept 队列争抢,减少锁竞争和上下文切换开销。
- 前提:Linux 内核 ≥ 3.9(
uname -r查),PHP ≥ 7.0,且stream_socket_server()底层支持SO_REUSEPORT - 效果:同配置下可比未开启时多撑 10–20% 连接,
count可往物理核数靠拢(如 8 核设 8~10,而非 16) - 验证是否生效:
ss -lnt | grep :端口看同一端口是否出现多行输出(每行对应一个 Worker 进程)
真正卡住性能的往往不是 count 数字本身,而是它背后暴露的瓶颈:内存不足时加进程只会更快 OOM,IO 阻塞时堆进程反而加剧 Recv-Q 积压。调参前务必先用 ss -lnt 和 ps aux 看清真实负载分布。











