Nodejs

lxf2023-03-18 12:53:02

本文带大家了解一下node里的Nodejs-cluster模块,介绍一下Nodejs-cluster模块用法,希望能帮助到大家!

Nodejs

招聘者有的时候会询问你,你给我说下nodejs怎么开启多线程哇,你脑海中就应当马上发生cluster模块,现如今让我陪你去讨论下cluster模块应用。

基本上使用方法

Node.js默认设置单进程运作,针对32位系统软件最大可以用512MB运行内存,针对64位最大可以用1GB运行内存。针对多核CPU的电子计算机而言,这么做效率不高,所以只有一个核在运行,别的核都是在闲置不用。cluster模块便是为了解决这个问题而所提出的。

cluster模块容许设立一个主过程和多个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\n");
  }).listen(8000);
}

上边编码先分辨现阶段过程是不是为主导过程(cluster.isMaster),假如是的,还是按照CPU的核数,新创建多个worker过程;要不是,表明现阶段过程是worker过程,即在该过程运行一个客户端程序。

以上这一段编码有一个缺陷,便是一旦work过程挂掉,主过程没法了解。为了解决这个问题,能够在过程布署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()的传参,代表一个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目标。下边是一个推送JSON目标的事例。

worker.send({
  type: 'task 1',
  from: 'master',
  data: {
    // the data that you want to transfer
  }
});

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

上边编码用于赋值全部worker过程。

现阶段socket的data事情,还可以用id特性鉴别worker过程。

socket.on('data', function(id) {
  var worker = cluster.workers[id];
});

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”事情就传向该过程服务器,随后传向主过程。

此次事件的调用函数接纳2个主要参数,一个是现阶段worker目标,另一个是详细地址目标,包括网站地址、端口号、详细地址种类(IPv4、IPv6、Unix socket、UDP)等相关信息。这对于一些服务项目好几个网址的Node应用软件非常有利。

不间断地重新启动Node服务项目

重启服务必须关闭后重新启动,运用cluster模块,能做到先运行一个worker过程,然后把原先的全部work过程关掉。那样就可以做到不间断地重新启动Node服务项目。

最先,主过程向worker进程传出重新启动数据信号。

workers[wid].send({type: 'shutdown', from: 'master'});

worker过程监视message事情,一旦发现内容包括shutdown,就撤出。

process.on('message', function(message) {
  if(message.type === 'shutdown') {
    process.exit(0);
  }
});

下边是一个全部关闭worker进度的函数公式。

function restartWorkers() {
  var wid, workerIds = [];
  for(wid in cluster.workers) {
    workerIds.push(wid);
  }

  workerIds.forEach(function(wid) {
    cluster.workers[wid].send({
      text: 'shutdown',
      from: 'master'
     });
    setTimeout(function() {
      if(cluster.workers[wid]) {
        cluster.workers[wid].kill('SIGKILL');
      }
    }, 5000);
  });
};

PM2控制模块

PM2控制模块是cluster模块一个外包装层。它的功能是尽量把cluster模块抽象化掉,让消费者像应用单进程一样,布署多线程Node运用。

// app.js
var http = require('http');

http.createServer(function(req, res) {
  res.writeHead(200);
  res.end("hello world");
}).listen(8080);

用PM2从cmd运行这些编码

$ pm2 start app.js -i 4

上边代码的i主要参数告知PM2,这一段编码需要在cluster_mode运行,且新创建worker进度的数量是4个。假如i主要参数数值是0,那样现阶段设备几个CPU内核,PM2便会运行好多个worker过程。

如果一个worker过程因为种种原因挂掉了,就会马上重新启动该worker过程。

# 重新启动全部worker过程
$ pm2 reload all

每一个worker过程都有一个id,能用下边的指令查询单独worker进度的详细信息。

$ pm2 show <worker id>

关掉worker进度的情况下,能够布署下边的代码,让worker过程监视shutdown信息。一旦接到这番话,开展结束收尾清洁工作再关掉

process.on('message', function(msg) {
  if (msg === 'shutdown') {
    close_all_connections();
    delete_logs();
    server.close();
    process.exit(0);
  }
});

大量node基本知识,请访问:nodejs 实例教程!!

以上就是关于聊一聊Nodejs-cluster模块,介绍一下其用法的具体内容,大量欢迎关注AdminJS其他类似文章!