CodeSamplez.com

Programming, Web development, Cloud Technologies

  • Facebook
  • Google+
  • RSS
  • Twitter
  • Home
  • Featured
    • C# Tutorials
      • LinQ Tutorials
      • Facebook C# API Tutorials
    • PHP Tutorials
      • CodeIgniter Tutorials
    • Amazon AWS Tutorials
  • Categories
    • Programming
    • Development
    • Database
    • Web Server
    • Source Control
    • Management
    • Project
  • About
  • Write
  • Contact
Home Development Getting Started With Nodejs Cluster

Getting Started With Nodejs Cluster

Rana Ahsan December 13, 2014 2 Comments


 Getting Started With Nodejs Cluster    

If you are already using nodejs for a while, you might already know that, nodejs is by default made up with single threaded architecture. That means, all your application logic will be run as a single thread for any amount of traffic requests. So, whenever it’s doing one operation, it won’t be doing anything else at that moment, even if there is a new request at the same time, which will have to wait. It may sound terrifying, but with its event-driven architecture, its doing the job quite well, as soon as one golden rule is followed, which is ‘each operations in nodejs should be done using minimum CPU time usage’. All CPU-heavy operations should be done somewhere else.

Well, that sounds fair. As soon as we know and follow this accordingly, our app should be fine doing its work in single threaded mode. However, still, if we get a very high traffic, where several requests per second need to be handled as fast as possible, single threaded architecture won’t do much good at that point, restricting you from scaling your application. So, what do we do?

NodeJS Cluster To The rescue:

Well, there is no direct facility to create multiple thread in a single nodejs application process, but there is facility to create multiple process to bind under same server port and work in the same way independently. Nodejs ‘cluster’ module facilitate this in a very efficient manner. We can implement multi-process architecture with it easily.

Creating a simple worker process:

Cluster module follows the master-slave/parent-child paradigm. So, the first process that will be run, is the master process, and all the other process that it creates, are workers. Lets see a small code snippet:

var http = require("http");

var cluster    = require('cluster');
if (cluster.isMaster) {
    var worker = cluster.fork();
}
else {
    http.createServer(function(req, res){
        res.end("Hello World");
    }).listen(1337);
}

As you can see here, we are checking if it’s the initial/master process by using ‘cluster.isMaster’ check. If so, we are forking a new process under it. Which will in turn will fall under ‘else’ block and create the child process, which does the actual work of server port binding. However, you may noticed that, the above code is going to create only two processes: one child and one master, where master is doing nothing else other than creating the child.

Creating multiple child processes and controlled by master:

Lets now move ahead a little to create more than one processes and make sure all of them get terminated if the master is terminated.

var http = require("http");

var cluster    = require('cluster');
if (cluster.isMaster) {
    var workers = [];
    for(var i=0; i<5; i++) {
      workers.push(cluster.fork());
    }
    process.on('SIGINT', function(){
        console.log("exiting "+process.pid);
        for(var i=0; i<5; i++) {
           console.log("destroying "+worker.process.pid);
           workers[i].destroy();
        }
    });
}
else {
    console.log("Child process "+process.pid+" being created and listening to port 1337");
    http.createServer(function(req, res){
        res.end("Hello World");
    }).listen(1337);
}

As you can see here, we are creating five child processes now and all of them are listening to same 1337 port. Besides, here our master process is also doing some significant tasks of making sure that all workers are terminated properly when the master process has to be terminated, so that there is not orphan child processes going to be around in the system.

Now all of these processes will share the same server port and listen together, though only process will be served with the request. If at some point 4 of them are already bg doing something, it still has room for getting another requests by the fifth one.

Some more failure recovery tuning:

Lets do some more awesome things. Lets assume, for some reason, our nodejs app is buggy and can crash anytime. Normally, you will might consider something like supervisord to monitor such process so that they respawn/restarted again automatically on crash events, to make sure your application is always alive. However, we can do that here internally, taken care of by the master process. A small example to give you idea how to do this is here:

var child = cluster.fork();
cluster.on('exit', function (worker, code, signal) {
        //logging details about what happend
        child = cluster.fork();;
});

Here, as soon as an exit event is observed, master process is creating another child process, so that, number of available processes are always be the same.

Making Your Life easier:

If you are wondering what if you could just tell very easily how many child processes to create and where to bind and all of these stuffs happens automatically? Yes, it’s quite possible, leaving you doing all of this staffs by yourself every time you create a nodejs application, you can consider using the clustered-node library, that I have created few days ago, which is both simple to use and eases migrating your existing nodejs app to multi-process mode.

Things To Remember:

  • Give Master Process Least Responsibility: It’s always recommended that, you shouldn’t give master process much responsibility as more responsibility means more risk to erroneous process, more chance to crash the master itself, leaving all children processes as orphans.
  • Don’t Just create many workers: You should consider original number of CPUs/cores while creating child processes. You shouldn’t just create several child processes on a single CPU core as they will share same computing power by context switching, which might make performance worse. General rule of thumb is number of child processes=number of cpu cores available.

Final Words:

Let me know if something isn’t clear of this tutorial via comments. Hope this will help you in some extent to start with nodejs cluster. Happy coding 🙂

Related

Filed Under: Development Tagged With: javascript, nodejs, scalability

About Rana Ahsan

Rana is a passionate software engineer/Technology Enthusiast.
Github: ranacseruet

Comments

  1. romain says

    March 26, 2015 at 5:57 pm

    Hi Ali! Nice writing, i’m wondering, what if cluster worker code is bad at initialization, if master respawns children immediately, they will also die, filling up your ram, and consuming all your CPU by spawning processes endlessly ( tested on my laptop. ) i’m developper here at dropncast interactive wall startup, and i’m verry concerned by this behaviour on app deployment. Could there maybe be a way to revert code if children keep dying immediately?

    Reply
    • Md Ali Ahsan Rana says

      March 28, 2015 at 12:08 am

      Hi Romain, an worker will be restarted only if if exited completely, so there shouldn’t be case of filling up memory. Instead, it suppose to help in case of memory leak issues. However, I am curious, if it still happens, that might be due to some kind of bug. As you are getting such behaviors, can you please share a code snippet so that I can have a look. However, may be adding an additional config variable to disable re-spawning is also a good idea in general way. I will keep that in mind and implement in future release of clustered-node library. Thanks.

      Reply

Leave a Reply Cancel reply

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

Email Subscription

Never miss any programming tutorial again.

Popular Tutorials

  • How To Work With JSON In Node.js / JavaScript
  • PHP HTML5 Video Streaming Tutorial
  • How To Work With C# Serial Port Communication
  • LinQ Query With Like Operator
  • Facebook C# API Tutorials
  • LinQ To SQL Database Update Operations In C#
  • Using Supervisord Web Interface And Plugin
  • Tutorial On Uploading File With CodeIgniter Framework / PHP
  • Utilizing Config File In C#.NET Application
  • Using GIT Plugin For Netbeans IDE

Recent Tutorials

  • Building Auth With JWT – Part 1
  • Document Your REST API Like A Pro
  • Understanding Golang Error Handling
  • Web Application Case Studies You Must Read
  • Getting Started With Golang Unit Testing
  • Getting Started With Big Data Analytics Pipeline
  • NodeJS Tips And Tricks For Beginners
  • Apple Push Notification Backend In NodeJS
  • Web Based Universal Language Translator, Voice/Text Messaging App
  • How To Dockerize A Multi-Container App From Scratch

Recent Comments

  • S. Chalisque on PHP HTML5 Video Streaming Tutorial
  • Armorik on Generate HTTP Requests using c#
  • iswaps on PHP HTML5 Video Streaming Tutorial
  • TAKONDWA on PHP HTML5 Video Streaming Tutorial
  • rorenzo on PHP HTML5 Video Streaming Tutorial

Archives

Resources

  • CodeSamplez.com Demo

Tags

.net apache api audio aws c# cache cloud server codeigniter deployment doctrine facebook git github golang htaccess html5 http image java javascript linq mysql nodejs oop performance php phpmyadmin plugin process python regular expression scalability server smarty ssh tfs thread tips ubuntu unit-test utility web application wordpress wpf

Copyright © 2010 - 2022 · CodeSamplez.com ·

Copyright © 2022 · Streamline Pro Theme on Genesis Framework · WordPress · Log in