15

I am using Express js and Node-cluster for taking the advantage of clustering I am also using PM2 for process and memory management. For a single machine, it is working fine, but my machine having 2 cores and I want to make available more cores. So I decided to join 3 more machines and now all 4 machines are connected using LAN. I am able to access the other machines using IP address in web browser also.

Now I want to connect all the machines and want to share their cores so that I will finally have 2 + 6 = 8 cores for my application. How can it possible? Is there any node module available to achieve this? Thanks.

Arpit Kumar
  • 2,179
  • 5
  • 28
  • 53
  • Arpit so how are you doing the session affinity between the request and different processes ? .If you have any articles of materials about it can u kindly point me to that simple clustering works but ones the session management and request continuity is considered the problem arises – codefreaK Jul 02 '18 at 16:58

2 Answers2

18

Node-cluster is good for taking advantage of multi core processors, but when it comes to horizontal scaling(adding more machines), you'll need to use load balancers or reverse proxy. For reverse proxy you can use any web server like Apache or nginx. If you want to rely on node and npm, there is a module by nodejitsu: http-proxy. Here is an example for http proxy for 3 machines running your node app.

  1. create a new node project.
  2. Install http-proxy module.

New version:

npm install --save http-proxy

If you prefer older version:

npm install --save http-proxy@0.8

  1. Create a new js file (server.js or anything you like).

For version 1.x.x (New)

server.js

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

var addresses = [
  {
    host: "localhost",
    port: 8081
  },
  {
    host: "localhost",
    port: 8082
  },
  {
    host: "localhost",
    port: 8083
  }
];

//Create a set of proxy servers
var proxyServers = addresses.map(function (target) {
  return new httpProxy.createProxyServer({
    target: target
  });
});

var server = http.createServer(function (req, res) {
  var proxy = proxyServers.shift();

  proxy.web(req, res);

  proxyServers.push(proxy);
});

server.listen(8080);

for version 0.x.x (Old)

server.js

var proxyServer = require('http-proxy');

var servers = [
  {
    host: "localhost",
    port: 8081
  },
  {
    host: "localhost",
    port: 8082
  },
  {
    host: "localhost",
    port: 8083
  }
];

proxyServer.createServer(function (req, res, proxy) {
  var target = servers.shift();

  proxy.proxyRequest(req, res, target);
  servers.push(target);
}).listen(8080);
  1. Now run this file.
  2. Request made to localhost:8080 will be routed to 8081, 8082 or 8083
  3. You can change the localhosts to IP addresses of your machines(and port numbers).

Clients making request to 8080 port are unaware of existence of servers at 8081, 8082 and 8083. They make requests to 8080 as if it is the only server and get response from it.

Now, one of the machines in your cluster will work as node balancer and application is hosted on other three machines. IP address of load balancer can be used as public IP.

Sandesh K
  • 919
  • 5
  • 10
  • Thanks, @Sandesh_k, I have Express js generated app folder structure in which I have `www` file in `bin` folder which creates the server and assigns the port so how should I apply this code in `www` file? – Arpit Kumar Feb 10 '17 at 10:15
  • This is just a proxy server... It does not need to be part of your application.. Just deploy it as a stand alone application... It will spit your requests across multiple hosts... – Sandesh K Feb 10 '17 at 10:17
  • @Sandesh_k, How should I make a request through the browser? I am making the request on `http://127.0.0.1:8080` it should go to proxy server first but t is directly going to the main server. – Arpit Kumar Feb 10 '17 at 10:58
  • Make request to your proxy server... it will route your requests to one of the hosts automatically... That means if your http-proxy is running at 8080 and application hosts are at 8081 and 8082, make request to 8080 and it will route them to any one of the hosts... – Sandesh K Feb 10 '17 at 11:02
  • This is how load balancing works... Client knows only about public server (which is a proxy server) but underneath requests are handled by a cluster of application servers of which client is unaware... – Sandesh K Feb 10 '17 at 11:06
  • You mean apart from the above code I need to create one more server using `http.createServer`? I have just copied the above code and changes the IP addresses and ports, should I add more code into it? – Arpit Kumar Feb 10 '17 at 11:08
  • Create a separate node application that will have above code and http-proxy module installed... Add ip and ports for your existing servers and start... now make request to this new server... – Sandesh K Feb 10 '17 at 11:13
  • This is generating this error: `Error: Must provide a proper URL as target` when I am making the request to `localhost:8080`; – Arpit Kumar Feb 10 '17 at 11:38
  • Yes, all three are started. But still, I am facing the same error. – Arpit Kumar Feb 10 '17 at 12:00
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/135374/discussion-between-sandesh-k-and-arpit-meena). – Sandesh K Feb 10 '17 at 12:03
  • Thanks, @sandesh_ . It's working now. Please look into chat I have a question related to the topic. – Arpit Kumar Feb 14 '17 at 08:00
  • 2
    @SandeshK Thanks for your answer, If one of my servers (for example port 3002) is not started or has an error, how can I automatically redirect requests to the other available server (i.e. port 3001)? – Kalai S Oct 30 '17 at 07:04
  • @KalaiS Good question... Solution is to use library like seaport and dynamically add nodes to load balancers... Check this tutorial: https://mazira.com/blog/introduction-load-balancing-nodejs-2 – Sandesh K Oct 30 '17 at 14:23
0

Horizontal scaling for node can be done in multiple ways :

  1. npm install http-proxy

    var proxyServer = require('http-proxy');
    var port = parseInt(process.argv[2]);
    var servers = [
      {
        host: "localhost",
        port: 8081
      },
      {
        host: "localhost",
        port: 8080
      }
    ];
    
    proxyServer.createServer(function (req, res, proxy) {
      var target = servers.shift();
    
      proxy.proxyRequest(req, res, target);
      servers.push(target);
    }).listen(port); 
    
  2. nginx

for more detail please check the below URL Horizontal scaling for node js

hasezoey
  • 998
  • 9
  • 24
Vora Ankit
  • 682
  • 5
  • 8