Кластер узлов: как назначить отдельный сервер/порт каждому воркеру?

Я понимаю, что могу использовать модуль Nodes cluster для создания нескольких рабочих процессов, обслуживающих одно и то же соединение сокета (пример из документации):

var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', function(worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
  });
} else {
  // Workers can share any TCP connection
  // In this case its a HTTP server
  http.createServer(function(req, res) {
    res.writeHead(200);
    res.end("hello world\n");
  }).listen(8000);
}

Однако что, если я вместо того, чтобы обслуживать одно и то же соединение, хочу, чтобы каждый рабочий сервер запускал свой собственный сервер, каждый из которых прослушивал отдельный порт?


person csvan    schedule 02.08.2015    source источник
comment
Я думаю, что основная причина кластера заключается в том, чтобы подразумевать многопоточность и эффективно использовать системный процесс. Например, одно соединение используется совместно с 4 процессами для балансировки нагрузки. Попробуйте использовать дочерний процесс для выполнения группы серверов (не пробовал просто идею)   -  person Sathish    schedule 02.08.2015
comment
почему ты хочешь сделать это? Похоже на проблему XY.   -  person Aaron Dufour    schedule 02.08.2015
comment
@AaronDufour Я пытаюсь сбалансировать нагрузку на несколько экземпляров socket.io. В разрабатываемом нами приложении основной единицей группировки пользователей является организация, и я хотел бы, чтобы каждая организация имела свой собственный сервер socket.io со своим собственным портом.   -  person csvan    schedule 02.08.2015
comment
@csvan Я думаю, вы получите лучшую производительность, если все процессы будут прослушивать все порты, чтобы каждый из них был сбалансирован по нагрузке, но я все равно ответил на ваш вопрос.   -  person Aaron Dufour    schedule 02.08.2015


Ответы (1)


Вы можете передавать переменные среды каждому дочернему процессу, позволяя главному процессу назначать им порты:

var cluster = require('cluster');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  var pidToPort = {}; 
  var worker, port;
  for (var i = 0; i < numCPUs; i++) {
    port = 8000 + i;
    worker = cluster.fork({port: port});
    pidToPort[worker.process.pid] = port;
  }

  console.log(pidToPort);

  cluster.on('exit', function(worker, code, signal) {
    // Use `worker.process.pid` and `pidToPort` to spin up a new worker with
    // the port that's now missing.  If you do so, don't forget to delete the
    // old `pidToPort` mapping and add the new one.
    console.log('worker ' + worker.process.pid + ' died');
  }); 
} else {
  // Start listening on `process.env.port` - but first, remember that it has
  // been cast to a string, so you'll need to parse it.
  console.log(process.env.port);
}
person Aaron Dufour    schedule 02.08.2015
comment
Мне нужен балансировщик нагрузки Nginx с восходящим потоком. Это мне очень помогло. Но я не понимаю, что лучше? Собственная кластеризация Node.js или балансировщик нагрузки Nginx или что-то другое? - person Enxtur; 04.10.2018