Sanu0074
@Sanu0074

Как правильно запустить nodejs-приложение в кластере на мультипроцессорной машине?

Берем пример из оф. документации:

if (cluster.isMaster) {
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
  });
} else {
  // start my application
}


В итоге приложение запустилось 8 раз (у меня core i7-4770K), все вроде бы правильно, но! В приложении есть cronjob'ы и повсеместно используются сокеты помимо http-сервера. Из-за этого, я постоянно вижу по несколько попыток соединения сокетов, при старте несколько раз читается и парсится один и тоже файл-конфиг (исп для инициализации настроек приложения), иногда это приводит к ошибками при попытке одновременного чтения. И это, я уверен, что еще не все грабли на которые я наступил при попытке запустить приложение на каждом ядре cpu.

Что мне делать теперь? Нужно ковырять все приложение и как-то костылить все чтоб не дублировалось в кластерном режиме? Или все же есть вариант сделать все безболезненно?
  • Вопрос задан
  • 456 просмотров
Решения вопроса 1
@xfg
Воспринимай каждый воркер как если бы он был запущен на удаленной машине, которая ничего не знает о другом воркере, который запущен на другой удаленной машине. Тогда станет ясно, что задачи следует складывать в сервер очередей, а тот уже раскидает задачи по воркерам так, чтобы они не пытались выполнять одновременно одну и ту же задачу.

Для очередей можно использовать kue. Работает поверх redis, который многие итак используют для масштабирования приложения по нескольким физически удаленным серверам, кеширования и всего прочего.

Конфиг можно подключать в индексном файле и отдавать каждой копии приложения.
const Application = require('path/to/Application');
const config = require('path/to/config');

if (cluster.isMaster) {
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
  });
} else {
  new Application(config).run();
}


Про сокеты не совсем понял. Приложение пытается куда-то приконектиться и выступает в роли клиента или приложение пытается поднять свой сокет сервер ?
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы