在 Node.js 中,由于 JavaScript 是单线程执行的,这意味着在面对高并发场景时,单线程的 Node.js 应用可能无法充分利用多核 CPU 的性能。为了解决这个问题,Node.js 提供了 cluster
模块,它允许我们创建多个 Node.js 进程,形成一个多进程集群,从而充分利用多核 CPU 的优势,提高应用的性能和并发处理能力。
主进程负责创建和管理子进程。它不处理具体的业务逻辑,主要的任务是监控子进程的状态,在子进程出现异常时进行重启等操作。
工作进程是实际处理业务逻辑的进程。主进程会将接收到的请求分发给工作进程进行处理。
cluster
模块的核心方法方法名 | 描述 |
---|---|
cluster.isMaster |
判断当前进程是否为主进程 |
cluster.fork() |
在主进程中创建一个新的工作进程 |
cluster.on('event', callback) |
监听集群事件,如 'exit' 事件可用于监听工作进程的退出 |
下面我们通过一个简单的 HTTP 服务器示例来演示如何使用 cluster
模块实现多进程集群。
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`主进程 ${process.pid} 正在运行`);
// 根据 CPU 核心数创建工作进程
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
// 监听工作进程退出事件
cluster.on('exit', (worker, code, signal) => {
console.log(`工作进程 ${worker.process.pid} 已退出,代码: ${code}, 信号: ${signal}`);
// 工作进程退出后,重新创建一个新的工作进程
cluster.fork();
});
} else {
// 工作进程创建 HTTP 服务器
http.createServer((req, res) => {
res.writeHead(200);
res.end(`你好,这是工作进程 ${process.pid}\n`);
}).listen(8000);
console.log(`工作进程 ${process.pid} 已启动,监听端口 8000`);
}
主进程部分:
cluster.isMaster
判断当前进程是否为主进程。for
循环根据 CPU 核心数调用 cluster.fork()
方法创建工作进程。'exit'
事件,当工作进程退出时,打印退出信息并重新创建一个新的工作进程。工作进程部分:
将上述代码保存为 cluster-example.js
,然后在终端中运行以下命令:
node cluster-example.js
你会看到类似以下的输出:
主进程 1234 正在运行
工作进程 1235 已启动,监听端口 8000
工作进程 1236 已启动,监听端口 8000
...
此时,你可以在浏览器中访问 http://localhost:8000
,多次刷新页面,你会发现每次返回的工作进程 ID 可能不同,这说明请求是由不同的工作进程处理的。
cluster
模块默认使用 round-robin
(轮询)算法进行负载均衡,将请求依次分发给不同的工作进程。通过使用 cluster
模块,我们可以轻松地创建多进程集群,充分利用多核 CPU 的性能,提高 Node.js 应用的并发处理能力。同时,主进程可以监控工作进程的状态,在工作进程出现异常时进行重启,保证应用的稳定性。希望本文能帮助你更好地理解和使用 Node.js 的 cluster
模块。