Node JS Cluster Module With Web Server Example

Node JS app execute in single thread. But if your machine has multiple cpu cores, it can also use multiple cpu cores use it’s cluster module. This can improve hardware usage efficiency. So you can make your Node JS app more scalable.

1. Node JS Web Server Cluster Example.

In this example we will create a http web server in Node JS. The web server has one cluster master process and two worker process. When the app start, the master process will create and initialize the two worker process. And when a http request come to the web server, cluster master process will pick a free worker process ( in round robin order )  to process the request.

1.1 Install Node JS Cluster Module.

But first you should make sure the Node JS cluster module has been installed.

  1. Open a terminal and execute npm list command like below.
    sh-3.2# npm list cluster -g
    /usr/local/lib
    └── (empty)
  2. If the result in step one is empty, then run npm install to install it. We install cluster module globally, commonly it is installed in /usr/local/lib/node_modules directory.
    sh-3.2# npm install cluster -g
    + [email protected]
    

1.2 Node JS Cluster Module Methods.

  1. isMaster : This attribute is used to check whether current process is cluster master process or not.
  2. fork():This method is used to fork a master child process.

1.3 Web Server Cluster Source Code.

Save below code in a file cluster_example.js. Open a terminal and run below js file. You can see the console print out cluster’s master and worker process id.

When browse http://localhost:8000 from google Chrome or Firefox, you can see different worker process different browser request from the web page message.

READ :   Node JS JSON String And JavaScript Object Conversion Example Vice Versa

But when you execute below code, you will find google Chrome request will be executed twice when browse same url once. This is because for one url request ( such as http://localhost:8000) , google chrome will generate two url request ( http://localhost:8000, http://localhost:8000/favicon.ico ), so we should filter out the /favicon.ico request in source code, this issue do not exist in Firefox and other browser.

// Include http, and cluster module.
var http = require('http');
var cluster = require('cluster');
// There are totally 2 cpu in machine.
var cpu_numbers = 2;

// Create a http web server object.
var server = http.createServer(function (req, res) {

    /* For google chrome, one url request will generate two request, one for "/favicon.ico" the other for "/".
       So to avoid the second request in one url request, we should filter out the favicon.ico request. */
    if(req.url!='/favicon.ico') {
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('Hello World from worker process ' + process.pid);
        console.log('Process request worker pid is ' + process.pid);
    }
})

// When app start.
if (cluster.isMaster) {
    // Print out the master pid.
    console.log('Master process id ' + process.pid)
    // Create worker process in cluster.
    for (var i = 0; i < cpu_numbers; i++) {
        // Invoke cluster fork method to create a cluster worker.
        var worker = cluster.fork();
        // Print out the worker pid.
        console.log('Worker ' + (i + 1) + ' process id ' + worker.process.pid);
    }
} else {
    // Make http web server listen on port 8000.
    server.listen(8000);
}

Below is console output.

/usr/local/bin/node /Users/zhaosong/Documents/WorkSpace/dev2qa.com-example-code/JavaScriptExampleWorkspace/NodeJSWorkspace/ClusterExample/cluster_example.js
Master process id 7555
Worker 1 process id 7556
Worker 2 process id 7557
Process request worker pid is 7556
Process request worker pid is 7557

browse http web server in cluster from firefox

browse node js http server cluster in google chrome

2. Make Node JS Cluster Work Continuously.

There is an issue in this example. When a worker process is stopped, the cluster will only have one worker. When all worker process stop, the cluster will fail.

READ :   How To Debug Node.js Application With Command Line

To avoid this issue, Node JS cluster module provide ‘online‘ and ‘exit‘ event. The two event will be triggered when a child worker process is created or stopped. So we can create a new worker when the exit event is happen. Thus the cluster will have enough worker to process client http request even when one worker stop.

So add below code in cluster_example.js

// When app start.
if (cluster.isMaster) {
    // Print out the master pid.
    console.log('Master process id ' + process.pid)
    ......

    cluster.on('online', function(worker){
       console.log('A new worker is online, worker process id is ' + worker.process.pid)
    });

    cluster.on('exit', function(worker, code, signal) {
        console.log('Worker ' + worker.process.pid + ' exit, status code is ' + code + ', and signal is ' + signal);
        console.log('A new worker will be started.');
        cluster.fork();
    });
}

Now run the example again. You can see below console output.

/usr/local/bin/node /Users/zhaosong/Documents/WorkSpace/dev2qa.com-example-code/JavaScriptExampleWorkspace/NodeJSWorkspace/ClusterExample/cluster_example.js
Master process id 7690
Worker 1 process id 7691
Worker 2 process id 7692
A new worker is online, worker process id is 7691
A new worker is online, worker process id is 7692

Kill worker process which process id is 7691 in terminal.

# kill 7691

You will see below console output which means exit and online event are all triggered, and a new worker is created after one worker exit.

Worker 7691 exit, status code is null, and signal is SIGTERM
A new worker will be started.
A new worker is online, worker process id is 7698
(Visited 77 times, 1 visits today)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.