Scaling Node.js Applications With PM2 Clusters

Node js was built on top of the V8 JavaScript engine. And we all know javascript is single-threaded, and our app runs in a single thread. So the complete utilization of the system resources was not happening.
When we have a computationally intensive logic that might potentially block that thread or when we have a sudden spike in our traffic that could potentially increase the latency of our services.
The node.js Cluster Module
The above issue can be solved with the help of the node.js Cluster module. The cluster modules create so many node application instances on separate workers (child processes) sharing port 8080 depending on the number of CPU cores available.
Let us take a simple node server as given below:
//server.js
const http = require("http");
http.createServer((req, res) => {
res.writeHead(200);
res.end("server endpoint hit");
}).listen(8080);
For implementing the cluster module, we have to wrap existing code with cluster logic as below:
//server.js
const http = require("http");
const os = require("os");
const cluster = require("cluster");
const cpuCores = os.cpus().length;
if (cluster.isMaster) {
let instance = 0;
while (instance < cpuCores) {
cluster.fork();
++instance;
}
} else {
console.log(`Child-process ${process.pid} started`);
http.createServer((req, res) => {
res.writeHead(200);
res.end("server endpoint hit");
}).listen(8080);
}
If we are running the application in an 8-core CPU system, the above clustering logic will create 8 separate worker instances(child process) sharing the same port thereby we are scaling the node.js application.
Drawbacks of the above method:
- We have to modify the existing code to implement clustering.
- If a child process was terminated, the new one wouldn’t be spawned to take its place unless we handle the exit event on the cluster instance.
PM2 Clusters(PM2 Ecosystem)
PM2 clusters overcome the above drawbacks. PM2 uses the Node.js cluster module to scale node.js applications across all CPUs available, without any code modifications.
Installing PM2
Before you can utilize PM2 to manage your Node.js application, you need to install its npm package first. Execute the command below to install pm2 globally on your computer:
npm install -g pm2
Create Config File
In the pm2 config file, we can set up pm2 to work in cluster mode, increase pm2 instances, post-deploy scripts, etc…
For creating a pm2 ecosystem config file, we can execute the following command:
pm2 ecosystem
The above command will create a file named ecosystem.config.js in your application directory as given below.
//ecosystem.config.js
module.exports = {
apps: [
{
name: "demo-app",
script: "server.js",
instances: 0,
exec_mode: "cluster",
watch: ".",
},
],
deploy: {
production: {
user: "YOUR_SSH_USERNAME_HERE",
host: "YOUR_SSH_HOST_ADDRESS",
ref: "YOUR_GIT_BRANCH_REF (eg: origin/master)",
repo: "GIT_REPOSITORY",
path: "YOUR_DESTINATION_PATH_ON_SERVER",
"pre-deploy-local": "",
"post-deploy":"npm install && pm2 reload ecosystem.config.js --env production",
"pre-setup": "",
},
},
};
In the above file :
- script: script path relative to pm2 start
- exec_mode: "cluster" tells PM2 to use the Node.js cluster module to execute the code.
- instances:0 when this is set to 0, PM2 will automatically spawn a number of child processes equal to the number of cores available in the CPU. Respawning to termination is handled by PM2 on its own.
- "post-deploy": "npm install && pm2 reload ecosystem.config.js -env production" The pm2 reloads which will make a zero-downtime deployment by adopting a rolling deployment approach where the instances are stopped and launched with the latest changes one after the other.
Start Application With PM2
Next, We can start our node application with PM2 as given below command:
pm2 start ecosystem.config.js
Now PM2 will create a number of instances of applications utilizing the system’s available cores without modifying the existing code.
Monitoring application metrics
Once your application is up and running, you can use PM2's list, show, and monit subcommands to keep tabs on how well your application is performing. First off, list all the running applications on your server with the pm2 list as shown below:
pm2 list
Restarting the application
One of the advantages of using a process manager like PM2 to manage your Node.js application in production is its ability to automatically restart the application when accidents occur. You can also restart your application at any time with the restart subcommand. It kills the process and relaunches it afterward:
pm2 restart ecosystem.config.js
For more deep knowledge see PM2 documentation.
On datainfinities.com, Read articles all around JavaScript, React, Node.js, PHP, Laravel, and Shopify.
Related Blogs
node: --openssl-legacy-provider is not allowed in NODE_OPTIONS
ERESOLVE unable to resolve dependency tree error when installing npm packages
Event Loop and Callback Queue in JavaScript
Cannot read property of undefined in JavaScript
Can't set headers after they are sent to the client
Remove an item from an array in JavaScript
How to Fix error:0308010C:digital envelope routines::unsupported
What is Call Stack in JavaScript
Find greatest common divisor (GCD) in JavaScript
Explore All Blogs