Nodejs + Express + Cluster Как использовать тот же порт? - PullRequest
0 голосов
/ 05 июля 2018

Итак, я экспериментирую с кластеризацией и сталкиваюсь с сообщением «Ошибка: связать EADDRINUSE ноль».

Конденсат (и испытанный) код:

var cluster = require('cluster');
if (cluster.isMaster) {
    // Count the machine's CPUs
    var cpuCount = require('os').cpus().length;

// Create a worker for each CPU
for (var i = 0; i < cpuCount; i += 1) {
    cluster.fork();
}
} else {
    var https = require('http');
    var express = require('express');
    var app = express();
    var serv = https.createServer(app);
    serv.listen(80);
    console.log("Server started.");
}

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

Ответы [ 3 ]

0 голосов
/ 05 июля 2018

Также можно использовать кластеры PM2, если вы используете менеджер процессов pm2. Кроме того, прокси-сервер ngnix может выступать в качестве балансировщика нагрузки.

0 голосов
/ 05 июля 2018

Ну, первый ответ правильный. Но я хочу, чтобы вы немного прояснили вопрос о кластеризации. Концепция кластеризации или разветвления вашего приложения на несколько процессов не означает, что вы запускаете несколько приложений на разных портах. На самом деле, концепция - это распределение.

Вскоре, если ваше приложение работает на порту 3000 только с одним процессом. Чтобы сделать его способным принимать больше нагрузки или распределять нагрузку по нескольким процессам, мы делаем кластеризацию. Поэтому я думаю, что вы понимаете, и после этого не должно возникать вопроса о другом порту.

Так что да, первый ответ правильный, сделать это самостоятельно, в любом случае, вы можете сделать это PM2.

0 голосов
/ 05 июля 2018

Я немного урезал плиту Express, но это общая идея:

var app = require('../app');
var http = require('http');
var cluster = require('cluster');

var port = process.env.PORT || '3000';
app.set('port', port);

// Code to run if we're in the master process
if (cluster.isMaster) {

  var cpuCount = require('os').cpus().length;

  // Create a worker for each CPU
  for (var i = 0; i < cpuCount; i += 1) {
      cluster.fork();
  }

} else {
  var server = http.createServer(app);
  server.listen(port);
  server.on('listening', onListening);
}

cluster.on('exit', function(worker) {
  console.log('Worker ' + worker.id + ' died :(');
  cluster.fork();
});

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
    console.log('Listening on ' + bind);
}

Ключевое отличие здесь - var app = require('../app'); вверху.

app экспортирует экспресс-экземпляр. Вы создаете по одному на каждого работника.

Попробуйте перестроить код на:

var cluster = require('cluster');
var https = require('http');
var express = require('express');
var app = express();

if (cluster.isMaster) {
    // Count the machine's CPUs
    var cpuCount = require('os').cpus().length;

    // Create a worker for each CPU
    for (var i = 0; i < cpuCount; i += 1) {
        cluster.fork();
    }
} else {
    var serv = https.createServer(app);
    serv.listen(80);
    console.log("Server started.");
}

Важная часть это

var serv = https.createServer(app);
serv.listen(80);

Заставить каждую форму сервера прослушивать порт 80 - вместо создания отдельных экземпляров app, которые все пытаются связывать и прослушивать этот порт, что приводит к ошибке EADDRINUSE.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...