Answer the question
In order to leave comments, you need to log in
How to properly scale a nodejs application using cluster?
For starters, here's my crooked start script (crooked because it doesn't work right), I tried to comment everything in it to make it clearer for you:
#!/usr/bin/env node
const log = require("lib/log")(module);
require('globals'); //подключаем глобальные переменные global.****
const DatabaseController = require("lib/mysql"); //конструктор mysql запросов
const LocalizationController = require("localizationController"); //Загружает данные с локализацией из mysql в глобальные переменные
const CronJob = require('cron').CronJob;
const http = require('http');
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
var app = require('config/application'); //подключаем express со всеми его настройками (мидлвары, view-engine, роуты и др)
app.set('port', _G.cfg.port); //_G - глобальная переменная с конфигами и проч
var server = http.createServer(app);
var io = require('base/socket')(server); //подключаем socket.io, в 'base/socket' находятся основные события connect/disconnect, авторизация сокета и др.
var redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));
if (cluster.isMaster) {
var i = 0; //поскольку мы в мастере, стартуем тестовую кронджобу, предпологаем что они будут выполняться только в мастере
let job = new CronJob('* * * * * *', function() {
log.info(`You will see this message every second: ${i}`);
i++;
}, null);
job.start();
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
log.info(`worker ${worker.process.pid} died`);
});
} else {
// для воркеров
server.listen(_G.cfg.port,()=>{ //запускаем сервер на нашем порту из конфига
LocalizationController.refreshLocales(() =>{ //загружаем локализации из бд в глоб переменную
let cc = DatabaseController.cacheController; // DatabaseController.cacheController - экземпляр для работы с redis
cc.getByMask(`${_G.cfg.session.matchingID}:*`,(err,data) =>{ //из redis загружаем все сессии
for(let i in data){
_G.sess[i.split(':').pop()] = data[i]; //кладем в глобальную переменную соответствие id-юзера и session-id
//их мы потом будем использовать для отправки данных нужному сокету
}
app.set('io', io);
log.info(`App listen port: "${server.address().port}"`);
});
});
});
server.on('error', (error) =>{
//error handler
});
}
Answer the question
In order to leave comments, you need to log in
The problem here is that all processes have their own global variables, but you need to somehow generalize them, if one process changes something in global variables, then this change should be duplicated for all processes.
if one process changes something in global variables, then this change should be duplicatedIn fact, if you refactor the code, it may very soon become clear that you didn’t really need it, and it seems like global variables weren’t really needed.
Everything can be done much easier, look towards PM2
pm2.keymetrics.io/docs/usage/cluster-mode
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question