CopyDisable

Friday 19 June 2015

Using PM2 process manager for node.js

 
PM2 (Process Manager 2) https://github.com/Unitech/PM2 is a process manager for Node.js applications. Some of its features are:
· PM2 allows us to run our application as multiple processes, without having to modify our application.
· It has built-in load balancing capabilities for running node.js application in cluster.
· It keeps the application up by restarting the application if it crashes.
· It can start the node application as a service when we restart the server.

 

Note: For this post I used Ubuntu 14.04

 

Installing node.js

Run the below command as root user or use sudo
# curl -sL https://deb.nodesource.com/setup | sudo bash -
clip_image002
clip_image004
Now run apt-get to install node.js
# apt-get install nodejs
clip_image006

Update 22/07/2015:
******************************************************

Suppose you want to install a different version of nodejs (at the time of writing this post the default setup was 0.10), for example suppose if I want 0.12, then go to the NodeJS github link:
https://github.com/nodesource/distributions/tree/master/deb

There you will get setup scripts for different versions of NodeJS, for my requirement of version 0.12 the script is setup_0.12, from the script get the link of the script and run the curl command:

curl -sL https://raw.githubusercontent.com/nodesource/distributions/master/deb/setup_0.12 | sudo bash -

After that run apt-get install nodejs command.

******************************************************


For testing cluster I created a small application test.js, this application shows the Process ID of the process which served the request:
For this application I need process module, install process module
clip_image008
 
My test.js file:
var http = require("http");
var process = require('process'); 

function onRequest(request, response){
response.writeHead(200, {"Content-Type" : "text/html"});
response.write('Request served by: ' + process.pid);
console.log(process.pid);
response.end();
}

http.createServer(onRequest).listen(8888);
console.log("Server has started.");
 
 
The sample output of this app:
clip_image010
 
Now I am going to install pm2 and run my test.js application using pm2.
 

Installing PM2:

$ sudo npm install pm2 -g
clip_image011

 

Running our application with pm2

Now we will start our test application using pm2 and will run multiple processes to form our cluster.
$ pm2 start test.js --name "testapp" -i 0
Options:
--name : This will specify a name for our application. This name can be used in other pm2 commands.
-i : Start the application in cluster mode, and the number of processes to run. A value of 0 informs pm2 to start as many worker processes as you have CPU cores.
clip_image013
So in our case we have 2 core CPU, so pm2 started 2 processes for our application.
 

Monitoring our application:

We can use the following pm2 commands to monitor our application:
Get list of applications monitored by pm2:
$ pm2 list
clip_image015
 
To get more details about an application:
$ pm2 show testapp
This will return details of all the processes running for that application. To get more details about a process, we can use the pm2 id for that process
$ pm2 show 1
Same output we can get using the pm2 desc command.
clip_image017
image
 
Monitoring the processes with CPU and RAM usage:
$ pm2 monit
clip_image021
The blue bar shows CPU usage and red one shows RAM usage for a particular process.
 

Checking logs of all the monitored processes:

$ pm2 logs
pm2 logs command shows tail command kind of output from all the log files. Log files for each individual processes are generated in PM2_PROCESS_USER_HOME_DIRECTORY/.pm2/logs directory.
So in my case /home/pranabs/.pm2/logs
clip_image022
clip_image024
To clean up the log files:
$ pm2 flush
clip_image025
 
To check if the cluster is working fine, I open my testapp in browser which displays the PID of the worker process which served the request.
clip_image027

clip_image029

clip_image030

If I keep refreshing the page, I could see different PIDs. If I check the displayed PIDs, I could find these PIDs in pm2 list command. This means that the user requests are being served from different processes which indicates some sort of load balancing is working in our cluster.

 


Restarting application:

pm2 reload <APP_NAME/all>
To restart all the monitored applications:
$pm2 reload all
To restart a particular application:
$pm2 reload testapp
clip_image032

 


Stopping application:

We can stop particular process/application or all applications
$ pm2 stop testapp
clip_image033

 

 

To remove application from pm2:

We can delete particular process/application or all applications from pm2
$ pm2 delete testapp
clip_image035

 

 

Checking auto start of failed process:

pm2 automatically starts a failed process. To verify that we will forcefully kill one of the processes and check whether pm2 starts another process for the failed one. Here I killed the process 5910, and we could see in the below screenshot that pm2 had started another process with ID 5939.
clip_image037

 

 

 

Starting applications automatically at server boot time

We can run the command pm2 startup to create the init script and deploy that init script to run at system startup.
To auto detect the platform just run pm2 startup:
$ pm2 startup
Also we can specify the platform with the startup command:
$ pm2 startup [platform]
The available options for platform are ubuntu, centos, redhat, gentoo, system, darwin and amazon
As I am using Ubuntu, so I am specifying ubuntu
$ pm2 startup ubuntu
This command will give us a command to run as root, which will actually deploy the init script at system startup.
sudo env PATH=$PATH:/usr/bin pm2 startup ubuntu -u pranabs
clip_image039
If we want to run the application as root, then we can directly run the pm2 startup command as root and it will deploy the necessary startup scripts.
clip_image041
Next run pm2 save command so that pm2 saves the currently monitored processes. The saved processes will be automatically started by pm2 when the system boots.
$ pm2 save
clip_image042
PM2 is very convenient tool for running node.js applications and the clustering is a very powerful feature. So try and enjoy pm2 Smile .


2 comments:

Unknown said...

Hi, I work for Shark Ninja and we have node.js applications running on one host. I would like to use a Load Balancer to direct traffic between both hosts. Ultimately I would like to load balance/cluster Node.js micro-services across two physical hosts. PM2 is used to start Node.js apps. Can you direct me to how this can be accomplished? Thank you - Sam Navarro

Pranab Sharma said...

You can have Nginx in front of your Node.js and let Nginx pass web requests off to your Node.js processes running on multiple hosts. Nginx can act as a load balancer and can distribute web requests amongst a group of processes running on the same server or multiple server.
Also another possibility in my mind is to use a Varnish cache server, which can also load balance your web requests to multiple hosts.

Post a Comment