Gateway进程数过多会导致连接资源浪费、网卡带宽争抢、内网IP连接数上限触发及TIME_WAIT拥塞,单台建议5–10万WebSocket连接;BusinessWorker过少则成处理瓶颈,需按响应时间与并发量合理配置;两者须全连通部署,比例失衡将引发Broken pipe或Too many open files错误。

Gateway 进程数太多会导致连接资源浪费
Gateway 进程只做网络 IO,每个进程默认会监听一个本地端口(由 startPort 指定),并维持成千上万客户端连接。但它的 CPU 消耗极低,瓶颈在内存和文件描述符——每个连接占约 2–3 KB 内存,加上 TCP 缓冲区,10 万连接就可能吃掉 200 MB+ 内存。
常见错误是盲目按 CPU 核数配 Gateway 数量,比如 16 核服务器直接设 $gateway->count = 16。结果:多个 Gateway 进程争抢同一块网卡带宽、共享同一个内网 IP 的连接数上限(如 Linux 默认 net.ipv4.ip_local_port_range 限制)、甚至触发 TIME_WAIT 拥塞。
- 单台 Gateway 进程轻松支撑 5–10 万 WebSocket 连接(取决于消息频率和包大小)
- 超过 8 个 Gateway 进程后,
lanIp和startPort配置稍有偏差,就会出现部分 Gateway 注册失败或 BusinessWorker 连不上 - 过多 Gateway 会让 Register 进程的地址广播压力陡增,尤其在节点频繁上下线时
BusinessWorker 进程太少会成为消息处理瓶颈
BusinessWorker 才真正执行 onMessage 里的 PHP 逻辑:查数据库、调 API、序列化 JSON、调用 Gateway::sendToGroup()。它吃 CPU、占内存、还可能阻塞——一旦某个请求耗时 200ms,整个进程就卡住,后续消息排队。
所以它的数量不能只看 CPU 核数,更要看业务平均响应时间。例如:
统一LLM网关 - 一个API对接70+AI模型,使用单一API密钥即可调用GPT、Claude、Gemini、Qwen、Deepseek、Grok等主流模型。
- 纯登录/心跳类逻辑($worker->count = CPU核数 × 2 通常够用
- 含数据库查询或外部 HTTP 请求(平均 80–150ms),建议按
并发连接数 ÷ 500初步估算,再压测调整 - 如果日志里频繁出现
WARNING Worker process timeout,说明单个 BusinessWorker 处理不过来,必须加进程数,而不是优化代码
Gateway 和 BusinessWorker 网络通信不是“1:1”,而是全连通
BusinessWorker 启动后,会主动连接所有已注册的 Gateway 进程(通过 registerAddress 获取地址列表)。也就是说,1 个 BusinessWorker 默认要建 N 个长连接(N = Gateway 总数),反过来,1 个 Gateway 也要接受 M 个 BusinessWorker 的连接(M = BusinessWorker 总数)。
这个“全连通”模型决定了比例失衡的后果很直接:
- Gateway 太少 + BusinessWorker 太多 → 单个 Gateway 被打爆,表现为大量
send() failed (32: Broken pipe)或心跳超时断连 - Gateway 太多 + BusinessWorker 太少 → BusinessWorker 连接数爆炸,
Too many open files错误频发,且消息转发路径变长(BusinessWorker → Gateway A → Gateway B → client) -
registerAddress配置错误(比如写成127.0.0.1而非真实内网 IP)时,BusinessWorker 可能连上错网段的 Gateway,导致sendToUid()完全失效,但日志里不报错
实际部署中容易被忽略的硬约束
很多团队在压测时发现连接数上不去,最后发现是系统级限制没调:
-
ulimit -n必须 ≥ (Gateway 连接数 + BusinessWorker 连接数 × Gateway 数)× 1.5,否则启动就失败 - Linux
net.core.somaxconn建议设为 65535,避免 accept 队列溢出 - Gateway 和 BusinessWorker 必须部署在同一内网段,且防火墙放行
startPort起始端口开始的连续端口段(如 2900–2903),不能只开一个端口 - Register 进程本身不参与消息流转,但它挂了,新启动的 Gateway/BusinessWorker 就无法互相发现——所以它必须用
systemd或supervisord守护,不能只靠-d参数
比例配置不是数字游戏,而是对连接生命周期、消息路径、系统资源三者的平衡。上线前务必用真实 client_id 绑定逻辑跑满载测试,别信理论值。

















