Horizontal Web-app Scaling with Nginx and Node.JS

One highly touted advantage of using Node.JS is that it makes applications easy to scale. This is true to an extent especially when it comes to web-apps.

A stateless request-response mechanism lends itself to parallelisation. This is as easy as spinning up another instance of the request handling process on the same or different machine.

Where state-full request-response is required (say to maintain session information) then to scale up the ‘state’ must be shared safely across different instances of the request handling processes. This separates out the ‘functional’ aspects of the request handling mechanism from the side-effect related code.

To tie in all the different web-app instances under a single public address and to load-balance across them we need a ‘reverse-proxy’. We will use Nginx for this.

Software needed:

  • Nginx (v 1.7.10)
  • Node.JS (v 0.10.12)

First let us setup the Nginx configuration:

[codesyntax lang=”javascript”]

events {
	worker_connections 768;
}

http {

	upstream localhost {
		server 127.0.0.1:18081;
		server 127.0.0.1:18082;
		server 127.0.0.1:18083;	
}
	server {
		listen 80;
		
		location / {
			proxy_pass http://localhost;
		}
	}
}

[/codesyntax]

 

More info about setting up and running Nginx – http://wiki.nginx.org/CommandLine

This configuration sets up the public address as localhost:80 with three private serving instances on the same machine at port: 18081, 18082 and 18083.

Let us also create a serving process in Node.JS using the Express framework:

[codesyntax lang=”javascript”]

var express = require("express");

var app = express();

var name = process.argv[2];
var PORT = process.argv[3] || 18080;

console.log("Server online: ",name,":",PORT);

app.get("/", function(request,response)
        {
           console.log("You have been served by: ",name,"on",PORT);

           response.write("Served by :"+name+" on "+PORT);
           response.end();
        });

app.listen(PORT);

[/codesyntax]

 

This takes in server name and port as the arguments.

We will spin up three instances of this serving process on the same machine with the  port numbers as in the Nginx config.

If we name the above as server.js then the instances can be spun up as:

node server.js <server_name> <port>

*Make sure you use the correct port (as provided in the Nginx config file).

Screen Shot 2015-03-22 at 01.51.15

 

Then just point your browser to localhost:80 and you should see:

Screen Shot 2015-03-22 at 01.56.33

 

Press refresh multiple times and you should see your request being served by different instances of web-app. Nginx by default uses ’round-robin’ load-balancing therefore you should see each of the instances being named one after the other as below (almost!).

Screen Shot 2015-03-22 at 01.56.45 Screen Shot 2015-03-22 at 01.58.15

 

Scaling out is as simple as spinning up a new instance and adding its IP and port to the Nginx configuration and reloading it.

 

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s