09.1
单线程与多核
Node 主线程是单条事件循环,默认只用到一个 CPU 核。要榨干多核,需用 cluster(多进程)或 worker_threads(多线程)。
| 方案 | 隔离 | 通信 | 适合 |
|---|---|---|---|
| cluster | 进程级 | IPC 消息 | HTTP 多实例负载 |
| worker_threads | 线程级 | MessageChannel | CPU 密集计算 |
09.2
cluster 多进程
cluster 为每个 CPU 核 fork 一个 worker,共享同一端口,由主进程分发连接。一个 worker 崩溃不影响其他。
import cluster from 'node:cluster';
import os from 'node:os';
if (cluster.isPrimary) {
for (let i = 0; i < os.cpus().length; i++) cluster.fork();
cluster.on('exit', w => cluster.fork()); // 自动重启
} else {
app.listen(3000);
}09.3
worker_threads
CPU 密集任务(压缩、加密、大计算)放进 worker,避免阻塞主事件循环。worker 间通过 postMessage 通信。
import { Worker } from 'node:worker_threads';
const w = new Worker(`
parentPort.on('message', d => parentPort.postMessage(d * 2));
`, { eval: true });
w.on('message', r => console.log('结果', r));
w.postMessage(21);选 cluster 还是 worker
I/O 密集的 HTTP 服务用 cluster 多实例即可;重计算用 worker_threads 把活移出主线程。
09.4
Stream 流式
处理大文件/大响应时,用流逐块读写,内存占用恒定,不会因为"一次性载入"而 OOM。
import { createReadStream, createWriteStream } from 'node:fs';
import { createGzip } from 'node:zlib';
createReadStream('big.log')
.pipe(createGzip())
.pipe(createWriteStream('big.log.gz')); // 全程流式,内存稳定09.5
诊断 perf_hooks
用 perf_hooks 测量耗时;用 0x / Clinic.js 做火焰图,定位最耗时的函数。
import { performance } from 'node:perf_hooks';
const t = performance.now();
await heavyWork();
console.log('耗时', (performance.now() - t).toFixed(1), 'ms');09.6
PM2 进程管理
PM2 是经典的生产进程管理器:守护、集群、日志、零停机重启。适合裸机/虚拟机部署。
npm i -g pm2
pm2 start dist/index.js -i max # 按核数起集群
pm2 logs # 查看日志
pm2 reload all # 零停机重启09.7
Docker 与优雅退出
容器化让环境一致。务必处理 SIGTERM 优雅退出:停止接收新请求、排空在途请求、关闭连接池。
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY dist ./dist
USER node
CMD ["node", "dist/index.js"]process.on('SIGTERM', async () => {
server.close(); // 停止接新连接
await pool.end(); // 关闭数据库连接
process.exit(0);
});优雅退出不可省
K8s 发 SIGTERM 后会给宽限期。不处理会导致在途请求被硬切断、连接泄漏。
09.8
常见陷阱与 FAQ
不共享。worker 是独立进程,内存隔离。需要共享状态用外部存储(Redis)或 IPC 消息。
如果是单条重计算阻塞了主线程,cluster 只是多份副本,单个请求仍慢。需把计算移入 worker_threads。
通常是 OOM 被 kill。检查内存泄漏、未流式处理的大对象,并合理设置容器内存上限。
09.9