Nodejs 利用cluster来让程序充分利用多核CPU

Nodejs 利用cluster来让程序充分利用多核CPU

在nodejs官方网站上面都可以看到这种代码

if(cluster.isMaster){
    for(var i = 0 ; i < numCPUS ; i ++){
        cluster.fork();
    }   
    cluster.on('exit',function(worker,code,signal){
        console.log('worker ',worker.process.pid," is died");
        process.exit();
    }); 
}else{
    http.createServer(app).listen(app.get('port'), function(){
      console.log('Express server listening on port ' + app.get('port'));
    }); 
    
}

请看中间的cluster.on(‘exit’)…这里面的部分

我相信很多人都希望当cluster结束后直接再重新开启,会将里面的process.exit()改为cluster.fork()

这一点比较关键,因为这么干了之后就会出现很多cluster.fork()绑定不上的情况,一直循环报错

所以还是让process退出,然后用supervisor脚本来重启这个进程比较合适


2 回复

Node.js 利用 cluster 来让程序充分利用多核 CPU

在 Node.js 中,cluster 模块提供了一种机制,可以让一个应用程序利用多核 CPU 的计算能力。通过创建多个工作进程(workers),每个进程可以独立地处理请求,从而更好地利用系统资源。

示例代码

以下是一个简单的示例,展示了如何使用 cluster 模块来启动多个工作进程:

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
    // 主进程
    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }

    cluster.on('exit', (worker, code, signal) => {
        console.log(`Worker ${worker.process.pid} died`);
        cluster.fork(); // 当工作进程退出时,重新启动一个新的工作进程
    });
} else {
    // 工作进程
    http.createServer((req, res) => {
        res.writeHead(200);
        res.end('Hello World\n');
    }).listen(8000, () => {
        console.log(`Worker ${process.pid} started on port 8000`);
    });
}

解释

  1. 主进程:

    • cluster.isMaster 判断当前进程是否为主进程。
    • 使用 cluster.fork() 创建与当前 CPU 数量相等的工作进程。
    • 监听 exit 事件,当工作进程退出时,重新启动一个新的工作进程。
  2. 工作进程:

    • 每个工作进程监听端口 8000,并响应 HTTP 请求。
    • 使用 http.createServer 创建一个简单的 HTTP 服务器。

关于 cluster.on('exit')process.exit()

在上述代码中,当工作进程退出时,主进程会自动重新启动一个新的工作进程。如果你尝试将 process.exit() 替换为 cluster.fork(),会导致新的工作进程不断启动,造成资源浪费和错误。

因此,最好的做法是在工作进程退出后,让主进程重新启动一个新的工作进程,而不是在工作进程中直接重新启动。你可以使用像 supervisor 这样的工具来监控和重启整个应用程序,以确保稳定运行。

总结

通过使用 cluster 模块,Node.js 应用程序可以有效地利用多核 CPU 的计算能力。主进程负责管理多个工作进程,并在工作进程退出时重新启动它们。这种方式可以显著提高应用程序的性能和稳定性。


为了充分利用多核CPU,可以使用Node.js的cluster模块。该模块允许你创建子进程(worker),这些子进程可以利用不同的CPU核心来执行任务。下面是一个完整的示例代码,展示了如何使用cluster模块来实现这一点。

示例代码

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
    console.log(`Master ${process.pid} is running`);

    // Fork workers.
    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }

    cluster.on('exit', (worker, code, signal) => {
        console.log(`Worker ${worker.process.pid} died`);
        console.log(`Starting a new worker`);
        cluster.fork();
    });
} else {
    // Workers can share any TCP connection
    // In this case it is an HTTP server
    http.createServer((req, res) => {
        res.writeHead(200);
        res.end('Hello World\n');
    }).listen(8000);

    console.log(`Worker ${process.pid} started`);
}

解释

  1. Master 进程:

    • isMaster 检查当前进程是否是主进程。
    • 主进程根据系统中的CPU核心数量创建相应数量的工作进程(worker)。
    • 监听工作进程的退出事件,并在工作进程退出时自动启动新的工作进程以保持服务的稳定性。
  2. Worker 进程:

    • 每个工作进程监听一个HTTP端口(例如8000)并响应请求。
    • 当接收到请求时,它会返回“Hello World”。

处理工作进程退出

如果你希望在工作进程退出后立即启动一个新的工作进程,可以在cluster.on('exit')事件处理函数中调用cluster.fork(),但这样做可能会导致进程频繁地启动和退出,从而导致性能问题或错误。

为了避免这种情况,通常建议在工作进程退出后让主进程退出,然后使用外部工具(如pm2forever)来监控并自动重启主进程。这样可以更好地管理资源,并避免频繁的进程重启带来的不稳定因素。

npm install -g pm2
pm2 start your-script.js --watch

这将确保你的应用能够在所有核心上高效运行,并且在工作进程退出后能够自动恢复。

回到顶部