zoukankan      html  css  js  c++  java
  • nodejs(四) --- cluster模块详解

    什么是cluster模块,为什么需要cluster模块? 

      cluster在英文中有集、群的意思。 

      nodejs默认是单进程的,但是对于多核的cpu来说, 单进程显然没有充分利用cpu,所以,node中的cluster模块就是为了解决没有充分利用cpu的问题而产生的。 

    cluster模块如何使用?

      cluster模块允许设立一个主进程和若干个worker进程(一般,我们对于产生的不是主进程的进程或者线程都用worker这个词来表示,打工者的意思),由主进程监控和协调worker进程的运行。worker之间采用进程间通信交换消息,cluster模块内置一个负载均衡器,采用Round-robin算法协调各个worker进程之间的负载。运行时,所有新建立的链接都由主进程完成,然后主进程再把TCP连接分配给指定的worker进程。

    var cluster = require('cluster');
    var os = require('os');
    
    if (cluster.isMaster){
      for (var i = 0, n = os.cpus().length; i < n; i += 1){
        cluster.fork();
      }
    } else {
      http.createServer(function(req, res) {
        res.writeHead(200);
        res.end("hello world
    ");
      }).listen(8000);
    }

    可以看到使用 cluster 模块是非常简单的,首先引入 cluster 模块,然后判断cup的个数,根据个数来创建子进程。 如果当前不是主进程,那么就启动一个服务器。

    但是,如果哪个进程挂了,我们无法检测到,所以,使用一个 online 和 exit来监听 :

    var cluster = require('cluster');
    
    if(cluster.isMaster) {
      var numWorkers = require('os').cpus().length;
      console.log('Master cluster setting up ' + numWorkers + ' workers...');
    
      for(var i = 0; i < numWorkers; i++) {
        cluster.fork();
      }
    
      cluster.on('online', function(worker) {
        console.log('Worker ' + worker.process.pid + ' is online');
      });
    
      cluster.on('exit', function(worker, code, signal) {
        console.log('Worker ' + worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal);
        console.log('Starting a new worker');
        cluster.fork();
      });
    }

    上面代码中,主进程一旦监听到worker进程的exit事件,就会重启一个worker进程。worker进程一旦启动成功,可以正常运行了,就会发出online事件。

    worker对象的使用

      worker对象是cluster.fork()的返回值,注意:fork方法可以返回一个v8实例,代表一个worker进程。属性和方法如下:

    (1)worker.id

    worker.id返回当前worker的独一无二的进程编号。这个编号也是cluster.workers中指向当前进程的索引值

    (2)worker.process

    所有的worker进程都是用child_process.fork()生成的。child_process.fork()返回的对象,就被保存在worker.process之中。通过这个属性,可以获取worker所在的进程对象。

    (3)worker.send()

    该方法用于在主进程中,向子进程发送信息

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

    上面代码的作用是,worker进程对主进程发出的每个消息,都做回声。

    在worker进程中,要向主进程发送消息,使用process.send(message);要监听主进程发出的消息,使用下面的代码。

    process.on('message', function(message) {
      console.log(message);
    });
    });
    

    发出的消息可以字符串,也可以是JSON对象。

    cluster.workers对象

    该对象只有主进程才有,包含了所有worker进程。每个成员的键值就是一个worker进程对象,键名就是该worker进程的worker.id属性。

    function eachWorker(callback) {
      for (var id in cluster.workers) {
        callback(cluster.workers[id]);
      }
    }
    eachWorker(function(worker) {
      worker.send('big announcement to all workers');
    });

    cluster模块的属性和方法

    isMaster,isWorker

    isMaster属性返回一个布尔值,表示当前进程是否为主进程。这个属性由process.env.NODE_UNIQUE_ID决定,如果process.env.NODE_UNIQUE_ID为未定义,就表示该进程是主进程。

    isWorker属性返回一个布尔值,表示当前进程是否为work进程。它与isMaster属性的值正好相反。

    fork()

    fork方法用于新建一个worker进程,上下文都复制主进程。只有主进程才能调用这个方法。

    该方法返回一个worker对象。

    kill()

    kill方法用于终止worker进程。它可以接受一个参数,表示系统信号。

    如果当前是主进程,就会终止与worker.process的联络,然后将系统信号法发向worker进程。如果当前是worker进程,就会终止与主进程的通信,然后退出,返回0。

    在以前的版本中,该方法也叫做 worker.destroy() 。

    listening事件

    worker进程调用listening方法以后,“listening”事件就传向该进程的服务器,然后传向主进程。

    该事件的回调函数接受两个参数,一个是当前worker对象,另一个是地址对象,包含网址、端口、地址类型(IPv4、IPv6、Unix socket、UDP)等信息。这对于那些服务多个网址的Node应用程序非常有用。

  • 相关阅读:
    HTML 常见标签part1
    HTML 初始
    jenkins远程执行脚本不退出
    jenkins 持续集成工具安装
    jenkins 杀掉衍生进程解决办法
    日志分割工具-crononlog
    可视化库 pygal 生成png中文乱码
    可视化库 pygal 无法保存成本地文件
    一个很好用的ORM库--peewee
    3 种进度条 -- 记录
  • 原文地址:https://www.cnblogs.com/zhuzhenwei918/p/7272349.html
Copyright © 2011-2022 走看看