workerman 4 进程数需据io/cpu密集类型与实测rss动态设定:io密集取cpu核数×3~5,cpu密集取核数或+1,混用场景先×2再调优;安全count≈(总内存mb×0.8)÷单进程rss;连接资源必须在onworkerstart初始化。

Workerman 4 的进程数($worker->count)不是固定套用“CPU核数×2”就能跑得稳,关键看业务阻塞特征和内存实际占用——设高了容易 OOM,设低了压不住并发,必须按 IO/CPU 密集倾向+实测 RSS 动态定。
先分清你的业务是 IO 密集还是 CPU 密集
这决定进程数的起点:
-
IO 密集型:代码里大量使用
mysqli、PDO、redis->get()等阻塞调用,每个请求会卡在等待数据库或 Redis 响应上。此时进程可设为 CPU 物理核心数 × 3~5(例如 4 核 → 12~20) -
CPU 密集型:全程用异步协程客户端(如
Webman\Support\AsyncMysql、Redis::coroutine()),或纯计算逻辑,无阻塞等待。进程数建议等于 CPU 物理核心数,或最多 +1(例如 4 核 → 4 或 5) -
混用场景:先按 ×2 设(如 4 核 → 8),再用
ps aux --sort=-%mem | grep php抓几个稳定 Worker 的 RSS 内存,结合top中各进程 %CPU 持续值判断偏向——若 %CPU 普遍低于 30% 但连接堆积,往 IO 密集方向调;若 %CPU 长期超 80%,往 CPU 密集方向收
内存才是硬上限,不是 CPU
每个 Workerman Worker 进程常驻内存通常在 30–60MB,取决于加载类库、OPcache、日志级别和中间件数量。别信“空进程才几 MB”的估算。
安全最大进程数公式:
最大安全 count ≈ (总内存 GB × 1024) ÷ 单进程 RSS(MB) × 0.8
举例:16GB 内存服务器,实测单 Worker RSS 为 48MB → 16 × 1024 ÷ 48 × 0.8 ≈ 273。那 $worker->count 就不能超过 270。
线上务必用 ps aux --sort=-%mem | grep php 抓 3–5 个运行 10 分钟以上的 Worker,取平均 RSS 值来算,不能靠文档预估。
初始化必须放在 onWorkerStart
所有连接资源(MySQL、Redis、HTTP 客户端等)必须在 onWorkerStart 回调中创建,不能写在全局或 onConnect 里。
原因:onConnect 每次新连接都触发一次,反复 new 对象会导致内存暴涨、连接泄漏;而 onWorkerStart 每个进程只执行一次,是唯一安全的初始化时机。
示例正确写法:
$ws_worker->onWorkerStart = function($worker) {<br> $worker->db = new PDO(...);<br> $worker->redis = new Redis();<br> $worker->redis->connect(...);<br>};
其他关键配套项
-
显式设置 count:不要依赖默认值,例如 8 核服务器,明确写
$ws_worker->count = 16;(IO 密集时)或= 8;(CPU 密集时) -
启用 reusePort:加
$worker->reusePort = true;,让内核把新连接均匀分发到各进程,避免默认 accept 队列竞争 - 控制 maxConnections:设为系统可用文件描述符上限的 70%~80%,留出空间给定时器、日志、DNS 查询等额外句柄











