
在 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 模块。