Nodejs-cluster模块知识点总结及实例用法

 更新时间:2021年12月14日 08:33:14   作者:青灯夜游  
在本篇文章里小编给大家整理的是一篇关于Nodejs-cluster模块知识点总结及实例用法,有兴趣的朋友们可以跟着学习下。

面试官有时候会问你,你给我说下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属性。

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”事件就传向该进程的服务器,然后传向主进程。

该事件的回调函数接受两个参数,一个是当前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从命令行启动这段代码

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

到此这篇关于Nodejs-cluster模块知识点总结及实例用法的文章就介绍到这了,更多相关Nodejs-cluster模块介绍内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • node.js中的events.emitter.once方法使用说明

    node.js中的events.emitter.once方法使用说明

    这篇文章主要介绍了node.js中的events.emitter.once方法使用说明,本文介绍了events.emitter.once的方法说明、语法、接收参数、使用实例和实现源码,需要的朋友可以参考下
    2014-12-12
  • 可能是全网最详细的nodejs卸载和安装教程

    可能是全网最详细的nodejs卸载和安装教程

    npm的中文意思为"node包管理器",是Node.js平台的默认包管理工具,会随着Nodejs一起安装,npm管理对应node.js的第三方插件,下面这篇文章主要给大家介绍了关于nodejs卸载和安装教程的相关资料,这可能全网最详细的教程了,需要的朋友可以参考下
    2023-05-05
  • 基于uniapp与node.js实现的微信授权登录功能实例

    基于uniapp与node.js实现的微信授权登录功能实例

    前端一直是一块充满惊喜的土地,不仅是那些富有创造性的页面,还有那些惊赞的效果及不断推出的新技术,下面这篇文章主要给大家介绍了关于如何基于uniapp与node.js实现的微信授权登录功能的相关资料,需要的朋友可以参考下
    2023-05-05
  • nodejs如何获取时间戳与时间差

    nodejs如何获取时间戳与时间差

    本文详细介绍了nodejs获取时间戳与时间差的多种方法,对平时nodejs的使用很有帮助,下面一起来看看吧。
    2016-08-08
  • 使用express+multer实现node中的图片上传功能

    使用express+multer实现node中的图片上传功能

    这篇文章主要介绍了使用express+multer实现node中的图片上传功能,需要的朋友可以参考下
    2018-02-02
  • nodejs读取本地mp3和mp4等媒体文件并播放的案例

    nodejs读取本地mp3和mp4等媒体文件并播放的案例

    fs模块是nodejs官方提供用来操作文件的模块,下面这篇文章主要给大家介绍了关于nodejs读取本地mp3和mp4等媒体文件并播放的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-09-09
  • Pycharm配置Node.js运行js代码详细过程

    Pycharm配置Node.js运行js代码详细过程

    在PyCharm中写JavaScript代码并进行调试是非常方便的,但是有些用户可能对如何在PyCharm中准确地运行JavaScript代码感到困惑,这篇文章主要给大家介绍了关于Pycharm配置Node.js运行js代码的相关资料,需要的朋友可以参考下
    2023-11-11
  • node.js使用zlib模块进行数据压缩和解压操作示例

    node.js使用zlib模块进行数据压缩和解压操作示例

    这篇文章主要介绍了node.js使用zlib模块进行数据压缩和解压操作,结合实例形式详细分析了node.js基于zlib模块创建数据流以及压缩和解压缩等相关操作技巧,需要的朋友可以参考下
    2020-02-02
  • Node.js操作MySQL8.0数据库无法连接的问题解决

    Node.js操作MySQL8.0数据库无法连接的问题解决

    使用node.js连接数据库MySQL 8时候,显示报错 ER_NOT_SUPPORTED_AUTH_MODE,本文就来介绍一下解决方法,感兴趣的可以了解一下
    2023-10-10
  • CentOS 8.2服务器上安装最新版Node.js的方法

    CentOS 8.2服务器上安装最新版Node.js的方法

    这篇文章主要介绍了CentOS 8.2服务器上安装最新版Node.js的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12

最新评论