Cluster 与多进程
cluster、keep-app-running。
30 分钟
Cluster 与多进程
单个 Node 进程默认 用一个 CPU 核跑 Event Loop。nrt-worker 解决线程级 CPU;cluster 模块让 多个 Node 进程共享同一端口,利用多核处理并发连接——经典「keep app running」模式。
学习目标
- 理解 master/worker(primary/worker)角色与端口复用
- 知道 cluster 与 PM2、容器多副本的关系
- 避免把有状态 session blindly 假设在单进程
基本 cluster 模板
import cluster from "node:cluster";
import http from "node:http";
import os from "node:os";
if (cluster.isPrimary) {
const n = os.availableParallelism();
console.log(`primary ${process.pid}, forking ${n} workers`);
for (let i = 0; i < n; i++) {
cluster.fork();
}
cluster.on("exit", (worker, code) => {
console.log(`worker ${worker.process.pid} exited ${code}`);
cluster.fork(); // 可选:自动重启
});
} else {
http.createServer((req, res) => {
res.end(`worker ${process.pid}\n`);
}).listen(3000);
}
OS 会在 primary 监听的端口上做 负载均衡(Linux 默认 round-robin 接受连接)。
生产环境现实
- PM2 cluster mode、Kubernetes 多 Pod 副本 是更常见的运维层多进程方案——原理类似:N 个独立进程 + 前面负载均衡。
- Nest / Express 无内置 session 亲和时,内存 session 会丢——用 Redis(见 nestjs-essentials)或 sticky session。
- 零停机重启:primary 先 fork 新 worker,再 SIGTERM 旧 worker——PM2 / 容器滚动更新更省心。
cluster vs worker_threads vs child
| 方案 | 粒度 | 共享 | 适用 |
|---|---|---|---|
| cluster | 多进程 | 不共享堆 | HTTP 多核、进程隔离 |
| worker_threads | 多线程 | 可选 SAB | CPU 计算 |
| fork 单个子进程 | 1+ 进程 | IPC | 跑脚本、隔离崩溃 |
不要在 cluster worker 里再 fork 大量子进程——进程数爆炸。
健康检查与 keep-alive
多 worker 下任一 worker crash,primary 可 cluster.fork() 补位;但 反复 crash 要限流,避免 fork 风暴。
配合 nrt-apm 上报 按 worker pid 分维度 的错误率与 heap。