Node.js集群:管理工作人员

Node.js集群:管理工作人员,node.js,multithreading,cluster-computing,worker,Node.js,Multithreading,Cluster Computing,Worker,我们正在深入研究Node.js体系结构,以充分了解如何扩展应用程序。 明确的解决方案是集群使用。除了工人管理层的描述外,一切似乎都很好: 但是,Node.js不会自动管理您的工作人员数量。您有责任根据应用程序的需要管理工作人员池 我在寻找如何真正管理员工,但大多数解决方案都说: 启动足够多的工人,因为你有核心 但我想根据服务器上的当前负载动态地增加或减少我的工作人员数量。所以,若服务器上有负载,并且队列越来越长,我想启动下一个worker。另一方面,当没有那么多负载时,我想关闭工人(并留下至少2

我们正在深入研究Node.js体系结构,以充分了解如何扩展应用程序。 明确的解决方案是集群使用。除了工人管理层的描述外,一切似乎都很好:

但是,Node.js不会自动管理您的工作人员数量。您有责任根据应用程序的需要管理工作人员池

我在寻找如何真正管理员工,但大多数解决方案都说:

启动足够多的工人,因为你有核心

但我想根据服务器上的当前负载动态地增加或减少我的工作人员数量。所以,若服务器上有负载,并且队列越来越长,我想启动下一个worker。另一方面,当没有那么多负载时,我想关闭工人(并留下至少2名工人)

对于我来说,理想的位置是主进程队列,以及新请求到达主进程时的事件。在这个地方,我们可以决定是否需要下一个工人

您是否有在集群中管理主线程工作人员的解决方案或经验?动态启动并杀死它们

问候,


Radek

以下代码将帮助您了解如何根据请求创建集群

该程序将在每10个请求中生成新集群

注意:您需要打开并刷新页面以增加请求

var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
var numReqs = 0;
var initialRequest = 10;
var maxcluster = 10;
var totalcluster = 2;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < 2; i++) {
    var worker = cluster.fork();
    console.log('cluster master');
    worker.on('message', function(msg) {
      if (msg.cmd && msg.cmd == 'notifyRequest') {
        numReqs++;
      }
    });
  }

  setInterval(function() {
    console.log("numReqs =", numReqs);
    isNeedWorker(numReqs) && cluster.fork();
  }, 1000);
} else {
  console.log('cluster one initilize');
  // Worker processes have a http server.
  http.Server(function(req, res) {
    res.writeHead(200);
    res.end("hello world\n");
    // Send message to master process
    process.send({ cmd: 'notifyRequest' });
  }).listen(8000);
}

function isNeedWorker(numReqs) {
  if( numReqs >= initialRequest && totalcluster < numCPUs ) {
    initialRequest = initialRequest + 10;
    totalcluster = totalcluster + 1;
    return true;
  } else {
    return false;
  }
}
var cluster=require('cluster');
var http=require('http');
var numpus=require('os').cpus().length;
var numReqs=0;
var initialRequest=10;
var-maxcluster=10;
var totalcluster=2;
if(cluster.isMaster){
//叉工。
对于(变量i=0;i<2;i++){
var-worker=cluster.fork();
log('cluster master');
worker.on('message',函数(msg){
如果(msg.cmd&&msg.cmd=='notifyRequest'){
numReqs++;
}
});
}
setInterval(函数(){
console.log(“numReqs=”,numReqs);
isNeedWorker(numReqs)和&cluster.fork();
}, 1000);
}否则{
log('cluster one initilize');
//工作进程有一个http服务器。
http.Server(函数(req,res){
书面记录(200);
res.end(“hello world\n”);
//向主进程发送消息
send({cmd:'notifyRequest'});
}).听(8000);
}
函数isNeedWorker(numReqs){
if(numReqs>=initialRequest&&totalcluster
以下代码将帮助您了解如何根据请求创建集群

该程序将在每10个请求中生成新集群

注意:您需要打开并刷新页面以增加请求

var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
var numReqs = 0;
var initialRequest = 10;
var maxcluster = 10;
var totalcluster = 2;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < 2; i++) {
    var worker = cluster.fork();
    console.log('cluster master');
    worker.on('message', function(msg) {
      if (msg.cmd && msg.cmd == 'notifyRequest') {
        numReqs++;
      }
    });
  }

  setInterval(function() {
    console.log("numReqs =", numReqs);
    isNeedWorker(numReqs) && cluster.fork();
  }, 1000);
} else {
  console.log('cluster one initilize');
  // Worker processes have a http server.
  http.Server(function(req, res) {
    res.writeHead(200);
    res.end("hello world\n");
    // Send message to master process
    process.send({ cmd: 'notifyRequest' });
  }).listen(8000);
}

function isNeedWorker(numReqs) {
  if( numReqs >= initialRequest && totalcluster < numCPUs ) {
    initialRequest = initialRequest + 10;
    totalcluster = totalcluster + 1;
    return true;
  } else {
    return false;
  }
}
var cluster=require('cluster');
var http=require('http');
var numpus=require('os').cpus().length;
var numReqs=0;
var initialRequest=10;
var-maxcluster=10;
var totalcluster=2;
if(cluster.isMaster){
//叉工。
对于(变量i=0;i<2;i++){
var-worker=cluster.fork();
log('cluster master');
worker.on('message',函数(msg){
如果(msg.cmd&&msg.cmd=='notifyRequest'){
numReqs++;
}
});
}
setInterval(函数(){
console.log(“numReqs=”,numReqs);
isNeedWorker(numReqs)和&cluster.fork();
}, 1000);
}否则{
log('cluster one initilize');
//工作进程有一个http服务器。
http.Server(函数(req,res){
书面记录(200);
res.end(“hello world\n”);
//向主进程发送消息
send({cmd:'notifyRequest'});
}).听(8000);
}
函数isNeedWorker(numReqs){
if(numReqs>=initialRequest&&totalcluster
要手动管理工作人员,您需要一个消息传递层来促进进程间的通信。在IPC中,主程序和工作程序可以有效地进行通信,默认情况下,该行为已在本机流程模块中实现。但是,我发现本机实现不够灵活或健壮,无法处理由于网络请求引起的水平扩展

一个显而易见的解决方案是将Redis作为消息代理来促进这种主从通信方法。然而,这种解决方案也由于其缺点,即上下文延迟,直接链接到命令和应答

进一步的研究使我想到了RabbitMQ,它非常适合在多个工作人员之间分配耗时的任务。工作队列(又称:任务队列)背后的主要思想是避免立即执行资源密集型任务并等待其完成。相反,我们将任务安排在以后完成。我们将任务封装为消息并将其发送到队列。后台运行的辅助进程将弹出任务并最终执行作业。当您运行多个Worker时,任务将在他们之间共享


要实现一个健壮的服务器,请阅读此链接,它可能会提供一些见解

要手动管理工作人员,您需要一个消息层来促进进程间通信。在IPC中,主程序和工作程序可以有效地进行通信,默认情况下,该行为已在本机流程模块中实现。但是,我发现本机实现不够灵活或健壮,无法处理由于网络请求引起的水平扩展

一个显而易见的解决方案是将Redis作为消息代理来促进这种主从通信方法。然而,这种解决方案也由于其缺点,即上下文延迟,直接链接到命令和应答

通过进一步的研究,我找到了RabbitMQ,它非常适合在多个工作人员之间分配耗时的任务。工作队列(也称为任务队列)背后的主要思想是避免立即执行资源密集型任务,而必须等待任务完成