On the server, instead of running node directly, we’ll run it with pm2.
Why use pm2 at all? What problem does it solve?
Think about it:
If your node app suddenly throws an error and crashes while you’re running, don’t you need to run it again? Wouldn’t you need another process to do the restarting automatically?
The node app’s logs are output on the console by default, if you want to output to a different log file, isn’t it possible to have another process fetch the node app’s output and write a file to achieve this?
node is single-threaded, while the machine is multiple cpu’s, in order to fully utilize the cpu’s capacity, we will use multiple processes to run the node application, this kind of generic logic can also be put into a single process to achieve?
Isn’t it necessary to monitor the cpu, memory and other resource usage when node is running? Couldn’t another process do it at this point?
Online node apps don’t just run, they do auto-restart, logging, multi-processing, monitoring, and more.
And all of these things can be done with pm2.
pm2 is process manager. It’s the second major version, and it’s so different from the previous one that it’s called pm2.
The main functions of pm2 are process management, log management, load balancing, and performance monitoring.
Let’s look at them separately:
First install pm2.
npm install -g pm2
Then run a node app, in my case a Nest.js app:
A direct node run looks like this, with logs printed on the console:
And with pm2, you can run it like this:
pm2 start ./dist/main.js
It will run this node process and then manage it:
Once it’s managed, there are all those features we talked about above, such as auto-reboot, log management, performance monitoring, and so on.
First look at the logs and execute
pm2 logs
You can see that pm2 prints out the logs of all processes, distinguished by the preceding “process id|process name”, such as 0|main.
Also, it writes it to a log file, under ~/.pm2/logs, with “process-name-out.log” and “process-name-error.log” for the different processes:
For example, main-out.log keeps the normal logs of the main process, while main-error.log keeps its error logs:
Let’s try running another process:
Now there are two processes. pm2 logs can see the logs of both processes:
pm2 logs
View the logs of individual processes in this way:
This is what pm2’s log management is all about.
Process management means that you can manually start, restart, and stop a process, and it will restart automatically when it crashes, or it can restart automatically at regular intervals.
Just need pm2 start with a couple of options:
Automatically reboot if memory exceeds 200M:
pm2 start xxx --max-memory-restart 200M
Reboot every 3s starting at 2s:
pm2 start xxx --cron-restart "2/3 * * * * *"
Automatically restarts when file contents change:
pm2 start xxx --watch
No automatic reboot:
pm2 start xxx --no-autorestart
Let’s try them separately:
Delete the previous process:
pm2 delete 0
We specify 1k memory and reboot:
pm2 start xxx --max-memory-restart 1K
Then use more than 1k of memory in the nest code:
Empty the previous log first, use pm2 flush or pm2 flush process name|id
It did clear out:
Access this controller:
View the first 100 lines of the main process log:
pm2 logs main --lines 100
Obviously saw the reboot.
This is an automatic reboot for exceeding memory.
Crash auto-reboot, timed auto-reboot, file change auto-reboot, etc. are also similar .
The pm2 start, pm2 stop, pm2 restart, pm2 delete, etc. that we used earlier are process management functions.
Then there’s load balancing. Node applications are single-process, and in order to take full advantage of multi-core cpu, we’ll use multi-process to improve performance.
The cluster module provided by node does this, and pm2 implements load balancing based on it.
All we have to do is start the process with -i num, which means start num processes for load balancing.
pm2 start app.js -i max
pm2 start app.js -i 0
These are the processes that start the cpu count.
Run the nest application in a multiprocessed fashion:
You can see that 8 processes are started because I have an 8 core cpu.
Once running, the number of processes can also be dynamically adjusted, via pm2 scale:
pm2 scale main 3
I adjusted the main’s cluster to 3 processes:
You can see that pm2 removed 5 and left 3.
pm2 scale main +3
I added 3 more and now it’s 6:
The number of processes can be scaled dynamically, and pm2 will assign requests to different processes.
This is the load balancing feature.
Additionally, there is a performance monitoring feature that runs pm2 monit.
pm2 monit
You can see the cpu and memory usage of different processes.
That’s about it, but when there are more processes, do they all have to be started manually from the command line?
Definitely not knocking it over every time.
pm2 supports starting multiple applications by means of configuration files.
Executing pm2 ecosystem creates a configuration file:
The apps section is for configuring the app, and scripts is the path to start the app:
There is a lot of configuration that can be specified, basically what options are available on the command line and what properties are available here:
Then pm2 start ecosystem.config.js to run a batch of apps.
It is equivalent to pm2 executing these commands automatically based on the configuration file, without us having to manually knock them out.
This way, we can save the startup options in the configuration file.
Finally, there’s pm2 plus, which is a paid feature, just check it out:
Visit pm2’s website, log in, and create a bucket:
Then run pm2 link xxx xxx locally to associate the local pm2 with that site:
Running pm2 plus again will open the bucket’s corresponding web page:
You can monitor your application online:
The following plus features are available for a fee:
You don’t usually need to use it either, just use the free local feature.
Some students say, “Isn’t docker deployment the norm now? Why do we still need pm2?
Of course you need it, docker containers also have multiple cpu’s, and you need to use pm2 for multi-process scaling and load balancing.
Processes within a docker container also have log management, process management, and monitoring needs.
It is common to run node with pm2 installed inside the docker image:
The node application on the server needs to use pm2’s log management, process management, load balancing, performance monitoring, and other features.
They correspond to the commands pm2 logs, pm2 start/restart/stop/delte, pm2 start -i, and pm2 monit, respectively.
Multiple applications or when you want to save the startup options, you can start a series of applications in bulk using the ecosystem configuration file.
Whether for purposes of stability, performance or observability, pm2 is essential.