Node中cluster模块基本用法是什么,能做什�
Admin 2022-07-29 群英技术资� 86 次浏�
面试官有时候会问你,你给我说下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”事件就传向该进程的服务器,然后传向主进程�
该事件的回调函数接受两个参数,一个是当前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); } });
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:[email protected]进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容�
猜你喜欢
在React的生命周期钩子和合成事件中,多次执行setState,会被调用几次,本文就详细的介绍一下,感兴趣的可以了解一�
js实现金额千分位方法,一些朋友可能会遇到这方面的问题,对此在下文小编向大家来讲解一下,内容详细,易于理解,希望大家阅读完这篇能有收获哦,有需要的朋友就往下看吧!
这篇文章主要介绍了解决Vue watch里调用方法的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
这篇文章主要介绍了javascript条件式访问属性和箭头函数,下面文章围绕条件式访问属性和箭头函数的相关资料展开文章内容,需要的朋友可以参考一�
JS实现表单验证案例 本文实例为大家分享了JS实现表单验证案例的具体代�,供大家参�,具体内容如下 1.当输入框失去焦点�,验证输入内容是否符合要求 (1)获取表单输入�(2)绑定 onblur 事件(3)获取输入内容(4)判断是否符合规则(5)如果不符合规�,则显示错误提示信� 2.当点击注册按钮是,判断所有输入框的内容是否符合要�,如果不符合则阻止表单提交 (1)获取表单对象(2)微表单对象绑� onsubmit(3)判断所有输入框是否都符合要�,如果符合,则返回true,如果有一项不符合,则返回false &l ...
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所�
增值电信经营许可证 : B1.B2-20140078