Be the first user to complete this post

  • 0
Add to List

Scaling a basic nodejs application using clusters

Nodejs derives its power from the asynchronous nature of javascript. However, the language also has one major caveat - its single threaded nature. This directly impacts the scalability in nodejs applications because if some of your requests consume considerable processor time then your thread is blocked and wont be able to process other incoming requests. If you have a machine with multiple cores, you can take advantage of this architecture by spawning multiple nodejs processes upto as many cpu's as are available to you such that each of these node processes listen on the same port. Such an arrangement is known as a nodejs cluster. On a linux machine, you can simply run the following command to check how many CPU's are available to you

nproc
If your number is greater than 1, then you are in good luck because now you can spawn multiple nodejs processes.

Initial setup

Lets first setup our package.json file. We will use expressjs to handle our requests.
{
    "name": "node-cluster-example",
    "version": "0.0.1"
}
Now install the latest version of express using
npm install express --save

Master and worker threads

Before we write our app.js file, there are 4 important things that you need to know.
  1. The process that runs as a result of running the node server from the command line becomes the master thread.
  2. The nodejs cluster module can be used within your code to distinguish between the master thread and worker threads.
  3. If the master thread is killed, so are the worker threads.
  4. When a worker thread exits unexpectedly, it fires an 'exit' event. You can listen to this event to spawn another thread if needed.
Below is the code we can use to setup a simple nodejs cluster
var cluster = require('cluster');
var express = require('express');
var app = express();
var port = 3000;
var cpus;
var i;

if (cluster.isMaster) {
  // The master thread is assigned the sole responsibility
  // of spawning child threads
  cpus = require('os').cpus().length;

  for (i = 0; i < cpus; i += 1) {
    // Here we create one worker thread per CPU
    cluster.fork();
  }

  cluster.on('exit', function (worker) {
      console.log('Worker ' + worker.id + ' exited');
      cluster.fork();
  });

} else {
  // Our app is initialized only on worker threads
  app = express();

  app.get('/', function (req, res) {
    res.send('Hello!, I am Worker #' + cluster.worker.id);
  });

  app.listen();
  console.log('App listening on port : ' + port);
}
Now you can simply run your app from the shell using
node app
And you will see as many App is listening on port messages as there are CPU's on your machine.



Also Read:

  1. Understanding expressjs middleware with a visual example
  2. Use node in es6 syntax with babel transpiling
  3. Find the environment variables of a nodejs process in linux
  4. Unit test your Nodejs RESTful API using mocha
  5. Organizing your expressjs routes in separate files.