初探 Cluster

初识 Cluster

最初接触Cluster是使用PM2部署Node项目:PM2可以根据当前CPU的核数为应用生成多个进程。通过 pm2 list 可以看到当前部署的任务,其中有些任务是 master模式,有些则是fork模式。在这里,PM2最大的好处就是不需要修改代码,就可以把应用扩展,以便于多核处理。

Pm2 Cluster mode

使用方式也很简单,在json配置文件中添加instance,允许的取值:

  • 0/max: 使用所有CPU
  • -1: 使用 所有CPU - 1
  • 数字n: 使用 n个CPU

参考: Cluster Mode - PM2

Node 中的 Cluster

为了更好的利用多核系统,有时会需要使用cluster进行多进程操作。通过cluster创建的子进程共享端口——这也是PM2中cluster mode的基础。

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`);
    });
    } 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`);
}

cluster使用fork来创建子进程worker,这些worker共享同一个端口。cluster有两种方式来调度子进程。第一种,也是默认的方法(windows系统除外)是轮询调度方法(round-robin approach)。简单的说,就是使用轮询调度算法加上部分优化调度进程,以防止某个worker过载。第二种方法是主进程(master process)创建监听socket,然后把连接调度给相关的worker。理论上,第二种方法的性能最好。但实际中,因为操作系统调度的影响,负载非常不均衡。例如,对于8核CPU,2个进程承担了大约70%的任务。
由于worker都是单独的进程,各自可以被销毁或重新生成而互不影响——这些都需要在应用中单独实现。所以,Nodejs并没有提供自动管理workers的机制,在实际应用中需要自己来维护workers。

更多资料可以参考官方API