node.js使用cluster实现多进程(2)

const childProcess = require('child_process'); const ls = childProcess.exec('rm spawn.js', function (error, stdout, stderr) { if (error) { console.log(error.stack); console.log('Error code: '+error.code); } console.log('Child Process STDOUT: '+stdout); });

正常情况下会删除spawn.js文件。

上面两个只是简单的运行进程的命令。 最后,(Boss总是最后出场的). 我们来瞧瞧fork方法的使用.
fork其实也是用来执行进程,比如,spawn("node",['app.js']),其实和fork('app.js') 是一样的效果的。但是,fork牛逼的地方在于他在开启一个子进程时,同时建立了一个信息通道(双工的哦). 俩个进程之间使用process.on("message",fn)和process.send(...)进行信息的交流.

child_process.fork(order) //创建子进程

worker.on('message',cb) //监听message事件

worker.send(mes) //发送信息

他和spawn类似都是通过返回的通道进行通信。举一个demo, 两个文件master.js和worker.js 来看一下.

//master.js const childProcess = require('child_process'); const worker = childProcess.fork('worker.js'); worker.on('message',function(mes){ console.log(`from worder, message: ${mes}`); }); worker.send("this is master"); //worker.js process.on('message',function(mes){ console.log(`from master, message: ${mes}`); }); process.send("this is worker");

运行,node app.js, 会输出一下结果:

from master, message: this is master from worker, message: this is worker

现在我们已经学会了,如何使用child_process来创建一个基本的进程了。
关于net 这一模块,大家可以参考一下net模块.

ok . 现在我们正式进入,模拟nodeJS cluster模块通信的procedure了。

out of date 的cluster

这里先介绍一下,曾经的cluster实现的一套机理。同样,再放一次图

node.js使用cluster实现多进程


我们使用net和child_process来模仿一下。

//master.js const net = require('net'); const fork = require('child_process').fork; var handle = net._createServerHandle('0.0.0.0', 3000); for(var i=0;i<4;i++) { fork('./worker').send({}, handle); } //worker.js const net = require('net'); //监听master发送过来的信息 process.on('message', function(m, handle) { start(handle); }); var buf = 'hello nodejs'; ///返回信息 var res = ['HTTP/1.1 200 OK','content-length:'+buf.length].join('\r\n')+'\r\n\r\n'+buf; //嵌套字 function start(server) { server.listen(); var num=0; //监听connection函数 server.onconnection = function(err,handle) { num++; console.log(`worker[${process.pid}]:${num}`); var socket = new net.Socket({ handle: handle }); socket.readable = socket.writable = true; socket.end(res); } }

ok~ 我们运行一下程序, 首先运行node master.js.
然后使用测试工具,siege.
siege -c 100 -r 2 :3000
OK,我们看一下,到底此时的负载是否均衡。

worker[1182]:52 worker[1183]:42 worker[1184]:90 worker[1181]:16

发现,这样任由worker去争夺请求,效率真的很低呀。每一次,触发请求,都有可能导致惊群事件的发生啊喂。所以,后来cluster改变了一种模式,使用master来控制请求的分配,官方给出的算法其实就是round-robin 轮转方法。

高富帅版cluster

现在具体的实现模型就变成这个.

node.js使用cluster实现多进程


由master来控制请求的给予。通过监听端口,创建一个socket,将获得的请求传递给子进程。

从tj大神那里借鉴的代码demo:

//master const net = require('net'); const fork = require('child_process').fork; var workers = []; for (var i = 0; i < 4; i++) { workers.push(fork('./worker')); } var handle = net._createServerHandle('0.0.0.0', 3000); handle.listen(); //将监听事件移到master中 handle.onconnection = function (err,handle) { var worker = workers.pop(); //取出一个pop worker.send({},handle); workers.unshift(worker); //再放回取出的pop } //worker.js const net = require('net'); process.on('message', function (m, handle) { start(handle); }); var buf = 'hello Node.js'; var res = ['HTTP/1.1 200 OK','content-length:'+buf.length].join('\r\n')+'\r\n\r\n'+buf; function start(handle) { console.log('got a connection on worker, pid = %d', process.pid); var socket = new net.Socket({ handle: handle }); socket.readable = socket.writable = true; socket.end(res); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgyjdf.html