Proxying and Balancing Requests With Node HTTP Proxy

The primary usage of node.js in production is as backend server. People use reverse proxy server which sits in front of node.js.

Nginx is a popular choice for proxy server. However if you are developing WebSocket (with socket.io) based app, it is not a viable solution yet. The alternative is HAProxy, which already supports WebSocket technology, but there seems to be issue with disconnection in forums.I have never tried so I cant confirm it.

My current choice for reverse proxy is Nodejitsu’s Node HTTP Proxy. It is used by nodejitsu.com so it should be reliable.

For my current scenario, I need to perform simple load balance for node.js processes and just proxy request for assets hosted in nginx. The problem is their ProxyTable doesn’t seem to handle custom logic. Node HTTP Proxy is code oriented approach ( you can argue that writing Nginx configuration is simpler) so it should be easy to write your custom logic with Node HTTP Proxy.

var http = require('http'),
    httpProxy = require('http-proxy'),
    url = require('url');

var app1Ports =[3xxx,3xxx,3xxx];//change this to your app ports
    
function roundRobin(host,ports){
    return function(req, resp, proxy){
        var currentPort = ports.shift();
        console.log('balancing request to: ', host,':',currentPort);
        proxy.proxyRequest(req, resp, { host: host, port: currentPort });
        ports.push(currentPort);
    };
}


//add any routes if you want 
var routes = [
    { host:'assets1.mystatic.com', port: 2xxx},//change this to your asset port
    { host: 'www.app1.com', handler: roundRobin('www.app1.com',app1Ports)}
];
    
        
function initProxy(){
    
    function internalProxy(req, resp, proxy){
        var re = new RegExp(req.headers.host);
        for(var i=0; i < routes.length; i++){
            var route = routes[i];
            if(re.test(route.host)){
                if(route.port){
                    proxy.proxyRequest(req, resp, route);
                    console.log('Proxying request to: ', route.host,':', route.port);
                }
                else
                {
                    route.handler(req, resp, proxy);
                }
                break;
            }
        }
    }
    
    httpProxy.createServer(internalProxy).listen(80, function(){
        console.log('Node http proxy run on port 80');
    });
    
}

process.title='nodeproxy';
initProxy();