Search This Blog

Thursday, February 15, 2018

Running Express.js in Cluster

Even if the computer has more than one CPU core, Node.js does not use all
of them by default. It only uses one CPU core for the main thread that
handles the event loop. So, for example, if you have a four-core system,
Node will only use one of them by default.

cluster module lets us create child processes that runs simultaneously
on common server port.Module enable the cluster module anyway
to increase your server availability and fault-tolerance

Including cluster in our express.js app

const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
const express = require("express");
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);

// Fork workers.
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}

cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
} else {
// Workers can share any TCP connection
// In this case it is an HTTP server
const app = express();
app.listen('3005', function () {
console.log('Listening on port:' + '3005');
});

console.log(`Worker ${process.pid} started`);
}

app.get("/", (req, res) => {
res.send("Hello World!");
});
app.get("/api/:n", function (req, res) {
let n = parseInt(req.params.n);
let count = 0;
if (n > 5000000000) n = 5000000000;
for (let i = 0; i <= n; i++) {
count += i;
}
res.send(`Final count is ${count} for ${n}`);
});

Run your express entry point as
node server.js

Output:
Master 23225 is running
Worker 23236 started
Worker 23249 started
Listening on port:3005
Listening on port:3005
Worker 23242 started
Listening on port:3005
Worker 23241 started
Listening on port:3005

Checking same through ps command on bash prompt

Run below command
ps -aux | grep server.js
Output:
sangram 23225 0.8 0.5 1023304 46656 pts/1 Sl+ 09:43 0:00 node server.js
sangram 23236 1.2 0.5 1022656 47044 pts/1 Sl+ 09:43 0:00 /usr/local/bin/node /home/sangram/xpw/app/server.js
sangram 23241 1.1 0.5 1022660 46728 pts/1 Sl+ 09:43 0:00 /usr/local/bin/node /home/sangram/xpw/app/server.js
sangram 23242 1.1 0.5 1022728 47292 pts/1 Sl+ 09:43 0:00 /usr/local/bin/node /home/sangram/xpw/app/server.js
sangram 23249 1.2 0.5 1022664 46992 pts/1 Sl+ 09:43 0:00 /usr/local/bin/node /home/sangram/xpw/app/server.js
Cluster on non-window platform follows round-robin approach,
where the master process listens on a port,
accepts new connections and distributes them across the workers
in a round-robin fashion, with some built-in smarts to avoid overloading
a worker process.

As workers are all separate processes, they can be killed
or re-spawned depending on a program's needs,
without affecting other workers. As long as there are some workers
still alive, the server will continue to accept connections.
If no workers are alive, existing connections will be dropped
and new connections will be refused.
It is the application's responsibility
to manage the worker pool based on its own needs.

Install Apache Benchmark Tool

sudo apt-get install apache2-utils

Now lets test

ab -c1000 -t10 http://localhost:3005/

This command will test-load the server with 1000
concurrent connections for 10 seconds.

Sample Output:

Server Software:
Server Hostname: localhost
Server Port: 3005

Document Path: /
Document Length: 139 bytes

Concurrency Level: 1000
Time taken for tests: 7.660 seconds
Complete requests: 50000
Failed requests: 0
Non-2xx responses: 50000
Total transferred: 20750000 bytes
HTML transferred: 6950000 bytes
Requests per second: 6527.02 [#/sec] (mean)
Time per request: 153.209 [ms] (mean)
Time per request: 0.153 [ms] (mean, across all concurrent requests)
Transfer rate: 2645.23 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 83 300.6 0 3048
Processing: 10 35 253.1 15 6634
Waiting: 10 35 253.1 15 6634
Total: 11 118 432.1 15 7648

Percentage of the requests served within a certain time (ms)
50% 15
66% 17
75% 18
80% 20
90% 34
95% 1036
98% 1241
99% 1452
100% 7648 (longest request)

using this tool you can find 'Requests per second','Time per request' ,
'no of failed request' etc.

References:
https://nodejs.org/api/cluster.html




No comments:

Post a Comment