cluster模块让Node.js充分利用多核资源

 2015年06月07日    1435     声明


Node.js 使用事件驱动,非阻塞I/O 模型而得以轻量和高效,Node程序都是单进程运行的。由于这些机制,使得Node.js并不能有效利用多核CPU资源。为了充分利用多核系统资源用户,需要运行一组Node进程来分担负载。cluster是Nodejs的内置模块,使用cluster模块,可以帮助我们实现Node程序的多进程运行,从而构建一个用于负载均衡的集群,且多进程共享监听同一端口。

  1. 使用示例
  2. 工作原理
  3. 进程间的通信


1 .使用示例

使用cluster模块,可以通过fork方法轻松的创建worker子进程,多个进程之间共享监听端口。现在多进程示例代码如下,文件名为server.js

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

if (cluster.isMaster) {
  // Fork启一个Worker 进程
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('listening',function(worker, address){
    console.log('worker ' + worker.process.pid +', listen: '+address.address+":"+address.port);
  });

  cluster.on('exit', function(worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
    //重启一个worker进程
    cluster.fork();
  });
} else {
  // Worker 进程之间可以共享任何形式的TCP连接
  // 在本例中是共享一个 HTTP 服务
  http.createServer(function(req, res) {
    res.writeHead(200);
    res.end("hello world\n");
  }).listen(8000);
  // 也可以启动一个express的web服务
  // var app = require('../app');
  // http.createServer(app);
}

以上代码为创建一个监听8000端口的HTTP服务,运行node server.js启动服务后,cluster会根据CPU核心数创建worker工作进程,master主进程负责管理工作进程。cluster模块也可以用于express框架中,只需将上面代码中创建HTTP服务器的代码替换为启动express app的代码即可。


2. 工作原理

cluster模块启动工作进程的使用fork方法,该方法其实是调用child_process模块child_process.fork方法创建子进程的。cluster模块fork方法调用成功后,会返回一个Worker类。

cluster没有路由的逻辑,因此多个worker工作进程之间没有状态共享。因此设计程序时要考虑到这一点,进程间共享状态要借助一些内存式状态存储方案,如 redis等。


3. 进程间的通信

child_process.fork方法创建子进程的时,会建立IPC(Inter-Process Communication,进程间通信)管道, cluster模块的多进程也是基于child_process.fork实现在的,因此也会建立IPC通信。借此机制,可以实现主进程master和工作进程worker之间的通信。

var cluster = require('cluster');

if (cluster.isMaster) {
  var worker = cluster.fork();
  worker.send('from master: hi there');
  worker.on('message', function(msg){
    console.log(msg);
  });
} else if (cluster.isWorker) {
  process.on('message', function(msg) {
    console.log(msg);
    process.send('from worker: hi there');
  });
}

运行结果如下:

from master: hi there
from worker: hi there


cluster模块还有一些进程管理的相关方法和相关事件的监听,请参考:cluster模埠集群类Cluster介绍cluster之工作进程类Worker介绍