A single instance of Node runs in a single thread. To take advantage of multi core systems the user will sometimes want to launch a cluster of Node processes to handle the load. The cluster module allows you to easily create a network of processes that all share server ports.
Code Example
A single threaded NodeJS server would have the following snippet
const http = require('http');
const port = 4000;
function init() {
startHttpServer();
}
function startHttpServer() {
var httpsServer = http.createServer(function (req, res) {
res.writeHead(200);
res.end("Hello Viewer!");
});
httpsServer.listen(port);
}
init();
The above code will run on a single core in your multi core environment
So to take advantage of NodeJs process & to fork our process to increase the software throughput, the below changes should be done
const os = require('os');
const http = require('http');
const cluster = require('cluster');
const port = 4000;
function init() {
if (cluster.isMaster) {
let numCPUs = os.cpus().length;
console.log(" Num of CPU ", numCPUs);
for (let idx = 0; idx < numCPUs; idx++) {
cluster.fork();
}
} else {
startHttpServer();
}
}
function startHttpServer() {
var httpsServer = http.createServer(function (req, res) {
res.writeHead(200);
res.end("Hello Viewer!");
});
httpsServer.listen(port);
}
init();
The cluster & os modules will help us achieve this. The above code gives us information about how much core our environment has.
In my system the Num of CPU is 8 ( This would be different based on your system & environment )
One main thing to notice is that the current process is the master because only the master can fork workers.
Master & Worker Communications
What we have understood untill this is, the cluster module is taking our processes and spawning it again as a separate process in the OS. There is no memory sharing between workers & master. In order to establish this we need to establish a communication message
const os = require('os');
const http = require('http');
const cluster = require('cluster');
const port = 4000;
function init() {
if (cluster.isMaster) {
let numCPUs = os.cpus().length;
console.log(" Num of CPU ", numCPUs);
for (let idx = 0; idx < numCPUs; idx++) {
let worker = cluster.fork();
worker.on('message', function (msg) {
console.log("Worker " + msg.worker + " served a " + msg.cmd);
worker.send("Good work!");
});
}
} else {
startHttpServer();
}
}
function startHttpServer() {
process.on('message', function (msg) {
console.log(msg);
});
var httpsServer = http.createServer(function (req, res) {
res.writeHead(200);
res.end("Hello Viewer!");
process.send({ worker: cluster.worker.id, cmd: 'request' });
});
httpsServer.listen(port);
}
init();
Here we have listeners for both the workers and the master. When the worker receives a request it sends a message to the master, which on receiving is printing some logs on the console and is returning a message to the worker that the worker also prints to the console.
Creating a multi-process NodeJS server is not difficult to do and can vertically scale your software improving its throughput. It is a very important part of using your hardware efficiently and scaling your applications.
Thanks for reading β€οΈ
Any other inputs or recommendations feel free to share below
Top comments (0)