Как правильно организовать многопроцессное приложение в Node.js?

132
29 декабря 2020, 08:40

Исходный код имеет следующий вид:

const listener = new Listener();
listener.start();
process.on('SIGTERM', () => {
  listener.stop();
});

Нужно разделить Listener на два таким образом, чтобы вынести аналогичную конструкцию в дочерний процесс (чтобы разделить нагрузку между ядрами процессора, например).

Как правильно это сделать средствами Node.js?

Answer 1

1. Разнородные дочерние процессы

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

./index.js

const { fork } = require('child_process');
const processHandlers = [
  './subprocess/process1.js',
  './subprocess/process2.js',
];
const processes = processHandlers.map((h) => fork(h, []));
process.on('SIGTERM', () => {
  processes.forEach((process) => process.send('stop'));
});

./subprocess/process1.js

const listener = new Listener1();    
listener.start();
process.on('message', (m) => {
  if (m === 'stop') {
    listener.stop();
    process.disconnect();
  }
});

./subprocess/process2.js

const listener = new Listener2();
listener.start();
process.on('message', (m) => {
  if (m === 'stop') {
    listener.stop();
    process.disconnect();
  }
});

2. Однородные дочерние процессы

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

const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
  // Обработчик ведущего процесса
  // Запуск дочерних процессов
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
  });
} else {
  // Обработчик дочерних процессов
  console.log(`Worker ${process.pid} started`);
}
READ ALSO
Rand() возвращает только половину из возможных значений, как бороться?

Rand() возвращает только половину из возможных значений, как бороться?

Функция rand() возвращает псевдослучайное число от 0 до 2^31 -1Она никогда не возвращает отрицательные числа, но при этом "ворует" аж половину диапазона...

107
Функция copy и set

Функция copy и set

Мне нужно переместить list в set, я думал что для этого можно использовать функцию copy, но все оказалось не так просто, так как у класса set нету метода...

126
Qt5: QSqlDatabase::close()

Qt5: QSqlDatabase::close()

Как правильно закрыть за собой соединение с базой данных?

153
Как понять что ввод начался? с++

Как понять что ввод начался? с++

Есть два потока, когда начинается ввод в одном требуется остановить другой поток, как понять что ввод в первом потоке началсяЕсли использовать:

116