48
loading...
This website collects cookies to deliver better user experience
mkdir nodejs-cluster
cd nodejs-cluster
npm init -y
npm install --save express
no-cluster.js
on the root of the project like below:no-cluster.js
file will be as follows:const express = require('express');
const port = 3001;
const app = express();
console.log(`Worker ${process.pid} started`);
app.get('/', (req, res) => {
res.send('Hello World!');
})
app.get('/api/slow', function (req, res) {
console.time('slowApi');
const baseNumber = 7;
let result = 0;
for (let i = Math.pow(baseNumber, 7); i >= 0; i--) {
result += Math.atan(i) * Math.tan(i);
};
console.timeEnd('slowApi');
console.log(`Result number is ${result} - on process ${process.pid}`);
res.send(`Result number is ${result}`);
});
app.listen(port, () => {
console.log(`App listening on port ${port}`);
});
3001
. It has two URIs (/
) that show Hello World!
and another path /api/slow
.math.atan()
, or an arctangent (in radians) of a number, and a math.tan()
, the tangent of a number. It adds these numbers to the result variable. After that, it logs and returns this number as the response.node no-cluser.js
and hit http://localhost:3001/api/slow
which will give us the following output:console.time
and console.timeEnd
calls.index.js
file that looks similar to the above no-cluster.js
file, but it will use the cluster module in this example. The code for the index.js
file looks like the below:const express = require('express');
const port = 3000;
const cluster = require('cluster');
const totalCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Number of CPUs is ${totalCPUs}`);
console.log(`Master ${process.pid} is running`);
// Fork workers.
for (let i = 0; i < totalCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
console.log("Let's fork another worker!");
cluster.fork();
});
} else {
startExpress();
}
function startExpress() {
const app = express();
console.log(`Worker ${process.pid} started`);
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.get('/api/slow', function (req, res) {
console.time('slowApi');
const baseNumber = 7;
let result = 0;
for (let i = Math.pow(baseNumber, 7); i >= 0; i--) {
result += Math.atan(i) * Math.tan(i);
};
console.timeEnd('slowApi');
console.log(`Result number is ${result} - on process ${process.pid}`);
res.send(`Result number is ${result}`);
});
app.listen(port, () => {
console.log(`App listening on port ${port}`);
});
}
express
module, then we require the cluster
module. After that, we get the number of CPUs available with require('os').cpus().length
. It was eight in my case on a Macbook Pro with Node.js 14 running.console.logs
we fork workers the same amount of times as the number of CPUs available. We just catch on the exit of a worker we log and fork another one.startExpress
function. This function is the same as the Express server in the previous example without clustering.index.js
file with node index.js
we see the following output:http://localhost:3000/api/slow
we will see the following output, identical to the output from the previous non-clustering server:node no-cluster.js
echo "GET http://localhost:3001/api/slow" | vegeta attack -duration=30s -rate=50 | vegeta report --type=text
200
response codes, meaning a 73.60 percent success rate without the cluster module.node index.js
echo "GET http://localhost:3000/api/slow" | vegeta attack -duration=30s -rate=50 | vegeta report --type=text
200
response code. The fastest response was in 31.608ms and the slowest was only 42.883ms compared to 21.745s without the cluster module.