node.js学习笔记(17) cluster

从笔记(14)就提及多进程,今日总算可以进入正题。

从v0.6.x开始,Node.js提供了多进程模块cluster,允许创建一组进程来共享同一个socket,并且分担负载压力。


官方文档是这样说的:

A single instance of Node.js runs in a single thread. To take advantage of multi-core systems the user will sometimes want to launch a cluster of Node.js processes to handle the load.

The cluster module allows you to easily create child processes that all share server ports.

单个node.js实例的运行是单线程的。用户有时候想运行一组进程来运行node.js实例以提高多核系统的性能。

cluster模块让你轻松创建可以共享服务端口的子进程。


那么试试先,用cluster共享一个http服务。

cluster-1.js:

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

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

    cluster.on('exit', function(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(function(req, res){
        res.writeHead(200);
        res.end('hello world, child-process:'+cluster.worker.id+'\n');
    }).listen(8000);
}


开启服务:


lee@mypc ~/works/nodejs/study17 $ node cluster-1.js


http访问效果:

lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:2
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:3
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:1
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:4
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:2
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:3
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:1
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:4
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:2
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:3
显然,虽然每次http访问都能得到结果“hello world”,但却并不是同一个进程。

并且我们可以看到cluster实现了的负载均衡,cluster会把请求依次分配给子进程2-3-1-4-2-3-1-4...........这是一个罗宾环。


cluster默认使用round-robin来实现负载均衡。也可以不使用round-robin。


lee@mypc ~/works/nodejs/study17 $ env NODE_CLUSTER_SCHED_POLICY="none" node cluster-1.js


这个时候,http访问的效果变成了随机:


lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:4
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:1
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:1
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:1
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:1
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:4
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:3
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:1




cluster是如何工作的?


cluster的工作进程是通过child_process.fork()来创建的,所以它们与父进程间可以进行通讯。

可以从源码中找到child_process.fork()的实现。

源码片段:

'use strict';

const EventEmitter = require('events');
const assert = require('assert');
const dgram = require('dgram');
const fork = require('child_process').fork;

......
  cluster.fork = function(env) {
    cluster.setupMaster();
    const id = ++ids;
    const workerProcess = createWorkerProcess(id, env);
    const worker = new Worker({
      id: id,
      process: workerProcess
    });
......

  function createWorkerProcess(id, env) {
    ......
    return fork(cluster.settings.exec, cluster.settings.args, {
      env: workerEnv,
      silent: cluster.settings.silent,
      execArgv: execArgv,
      gid: cluster.settings.gid,
      uid: cluster.settings.uid
    });
  }


上一篇:node.js学习笔记(26) node-orm进阶一


下一篇:情报智能研判预警平台建设,*大数据可视化系统开发