В кластере узлов несколько процессов прослушивают один и тот же порт

Я читал о кластерах в Node js, я наткнулся на простой пример, тогда как основной файл создает четыре дочерних процесса, и каждый из них слушает порт 8080.

Код работает хорошо, но я не получаю:

Как возможно иметь несколько дочерних процессов для прослушивания одного и того же порта?

Я ожидал получить сообщение типа

Ошибка: слушайте EADDRINUSE: адрес уже используется :::8080

const cluster = require("cluster");

if (cluster.isMaster) {
  for (let i = 0; i <= 4; i++) cluster.fork();
} else {
  require("./test.js");
}

test.js

const http1 = require("http");
http1
  .createServer((req, res) => {
    console.log("request1");
    res.write("hello1");
    res.end();
  })
  .listen(8080, () => {
    console.log("begin");
  });

person George Paouris    schedule 16.04.2020    source источник


Ответы (2)


Я сам задавался этим вопросом некоторое время назад и пошел копать.

Дочерние процессы не прослушивают один и тот же порт. Входящие соединения сокетов с главным процессом делегируются дочерним процессам.

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

Если бы я разрабатывал это, я бы, вероятно, не скрыл эту функциональность внутри .listen() и не стал причиной этой путаницы. Я бы предложил другой метод, который можно было бы использовать в этом случае, который имел бы такое особое поведение.

Если вы хотите узнать больше об этом, вот несколько ресурсов:

Исходный код для server.listen(), где видно, что он вызывает listenInCluster() при некоторых обстоятельствах.

В Net-документе для server.listen() есть ссылки на специальную обработку при кластеризации.

Сам listenInCluster() исходный код, в котором находится документ прочь:

  // Get the master's server handle, and listen on it
  cluster._getServer(server, serverQuery, listenOnMasterHandle);
person jfriend00    schedule 16.04.2020

дочерний процесс разделяет родительский fd, поэтому они прослушивают один и тот же порт. этот ответ может устранить путаницу

person Moazzam Arif    schedule 16.04.2020