Содержание
- Restart Strategies
- Restart strategies
- Restart at cron time
- Restart on file change
- Memory based restart strategy
- Restart Delay
- No Auto Restart
- Skip Auto Restart For Specific Exit Codes
- Exponential Backoff Restart Delay
- Quick Start
- PM2 Process Management Quick Start
- Installation
- Start an app
- Managing processes
- Check status, logs, metrics
- List managed applications
- Display logs
- Terminal Based Dashboard
- pm2.io: Monitoring & Diagnostic Web Interface
- Cluster mode
- Ecosystem File
- Setup startup script
- Restart application on changes
- Updating PM2
- CheatSheet
- What’s next?
- Programmer Help
- pm2 restart strategies
- Restart the application using a scheduled task
- Automatically restart the application after file changes
- Restart when application reaches memory threshold
- Delayed restart
- Prohibit automatic restart
- Specifies an exit code that does not restart automatically
- Exponential backoff restart delay
- Name already in use
- pm2-hive.github.io / docs / features / restart-strategies.md
Restart Strategies
Restart strategies
When starting application with PM2, application are automatically restarted on auto exit, event loop empty (node.js) or when application crash. But you can also configure extra restart strategies like:
- Restart app at a specified CRON time
- Restart app when files have changed
- Restart when app reach a memory threshold
- Delay a start and automatic restart
- Disable auto restart (app are always restarted with PM2) when crashing or exiting by default)
- Restart application automatically at a specific exponential increasing time
Restart at cron time
Via configuration file, use the cron_restart attribute:
To disable cron restart:
Restart on file change
PM2 can automatically restart your application when a file is modified in the current directory or its subdirectories:
Note: If an application is started with the —watch option, stopping the app will not prevent it to be restarted on file change. To totally disable the watch feature, do: pm2 stop app —watch or toggle the watch option on application restart via pm2 restart app —watch .
Via configuration file, use the watch: true attribute:
You can specify which folder to watch for change, ignore folder and watch files interval with these options:
Memory based restart strategy
PM2 allows to reload (auto fallback to restart if not in cluster) an application based on a memory limit/ Please note that the PM2 internal worker (which checks memory), starts every 30 seconds, so you may have to wait a bit before your process gets restarted automatically after reaching the memory threshold.
Via configuration file, use the max_memory_restart attribute:
Note: Units can be K(ilobyte) (e.g. 512K ), M(egabyte) (e.g. 128M ), G(igabyte) (e.g. 1G ).
Restart Delay
Set a delay between auto restart with the Restart Delay strategy:
Via configuration file, use the restart_delay attribute:
No Auto Restart
This is useful in case we wish to run 1-time scripts and don’t want the process manager to restart our script in case it’s completed running.
Via configuration file, use the autorestart attribute:
Skip Auto Restart For Specific Exit Codes
Sometimes you might want the application to automatically restart in case of failure (i.e. non-zero exit code), while not wanting the process manager to restart it when it shuts down properly (i.e. exit code equal to 0).
In this case, you can still use PM2 just fine with a stop_exit_codes option set to exit codes that should skip auto restart:
Or via configuration file, use the stop_exit_codes attribute:
Exponential Backoff Restart Delay
A new restart mode has been implemented on PM2 Runtime, making your application restarts in a smarter way. Instead of restarting your application like crazy when exceptions happens (e.g. database is down), the exponential backoff restart will increase incrementally the time between restarts, reducing the pressure on your DB or your external provider… Pretty easy to use:
Via configuration file, use the exp_backoff_restart_delay attribute:
When an application crash unexpectedly and the option —exp-backoff-restart-delay is activated, you will be able to see a new application status waiting restart.
By running pm2 logs you will also see the restart delay being incremented:
As you can see the restart delay between restarts will increase in an exponential moving average, till reaching the maximum of 15000ms between restarts.
When the application will then get back to a stable mode (uptime without restarts of more than 30 seconds), the restart delay will automatically reset to 0ms.
Источник
Quick Start
PM2 Process Management Quick Start
PM2 is a daemon process manager that will help you manage and keep your application online. Getting started with PM2 is straightforward, it is offered as a simple and intuitive CLI, installable via NPM.
Installation
The latest PM2 version is installable with NPM or Yarn:
To install Node.js and NPM you can use NVM
Start an app
The simplest way to start, daemonize and monitor your application is by using this command line:
Or start any other application easily:
Some options you can pass to the CLI:
As you can see many options are available to manage your application with PM2. You will discover them depending on your use case.
Managing processes
Managing application state is simple here are the commands:
Instead of app_name you can pass:
- all to act on all processes
- id to act on a specific process id
Check status, logs, metrics
Now that you have started this application, you can check its status, logs, metrics and even get the online dashboard with pm2.io.
List managed applications
List the status of all application managed by PM2:
Display logs
To display logs in realtime:
To dig in older logs:
Terminal Based Dashboard
Here is a realtime dashboard that fits directly into your terminal:
pm2.io: Monitoring & Diagnostic Web Interface
Web based dashboard, cross servers with diagnostic system:
Cluster mode
For Node.js applications, PM2 includes an automatic load balancer that will share all HTTP[s]/Websocket/TCP/UDP connections between each spawned processes.
To start an application in Cluster mode:
Read more about cluster mode here.
Ecosystem File
You can also create a configuration file, called Ecosystem File, to manage multiple applications. To generate an Ecosystem file:
This will generate an ecosystem.config.js file:
And start it easily:
Read more about application declaration here.
Setup startup script
Restarting PM2 with the processes you manage on server boot/reboot is critical. To solve this, just run this command to generate an active startup script:
And to freeze a process list for automatic respawn:
Read more about startup script generator here.
Restart application on changes
It’s pretty easy with the —watch option:
This will watch & restart the app on any file change from the current directory + all subfolders and it will ignore any changes in the node_modules folder —ignore-watch=»node_modules» .
You can then use pm2 logs to check for restarted app logs.
Updating PM2
We made it simple, there is no breaking change between releases and the procedure is straightforward:
Then update the in-memory PM2 :
CheatSheet
Here are some commands that are worth knowing. Just try them with a sample application or with your current web application on your development machine:
What’s next?
Learn how to declare all your application’s behavior options into a JSON configuration file.
Learn how to do clean stop and restart to increase reliability.
Monitor your production applications with PM2.io.
Источник
Programmer Help
Where programmers get help
pm2 restart strategies
use PM2 launch application When, the application will restart automatically when it exits automatically, the event loop is empty (node.js), or the application crashes. However, you can also configure additional restart policies, such as:
- Restart the application using a scheduled task
- Restart the application after the file changes
- Restart when application reaches memory threshold
- Delayed start and automatic restart
- By default, automatic restart is disabled on crash or exit (applications always restart using PM2)
- Automatically restart applications at specific exponential growth times
Restart the application using a scheduled task
Use the following command to set the task of scheduled restart
If yes configuration file If so, use cron_restart attribute:
Automatically restart the application after file changes
When the files in the current directory or its subdirectory are modified, PM2 can automatically restart your application:
Use the following command to start the application by specifying the option — watch later
Let’s illustrate this situation through gif dynamic diagram
Note: if the application starts using the – watch option, stopping the application does not prevent it from restarting when the file changes. To completely disable the watch function, execute the following command:
Or use the following command to switch the watch option when the application restarts.
In the configuration file, use the watch: true attribute
We can also specify which folder to listen to in the configuration file, and automatically restart the application when its contents are modified. You can also specify that some folders are ignored, and no restart will be triggered regardless of how their contents change
Restart when application reaches memory threshold
PM2 allows applications to be reloaded according to the memory limit (if they are not in the cluster, they will automatically fall back and restart) / please note that PM2 internal working program (check memory) starts every 30 seconds, so it may take a moment after reaching the memory threshold, and the process will restart automatically.
Use the — Max memory restart option to specify the memory threshold.
Use Max in configuration file_ memory_ Restart attribute.
Note: the units can be K(ilobyte) (e.g. 512K), m (egabyte) (e.g. 128M), G (igabyte) (e.g. 1G).
Delayed restart
Use the Restart Delay policy to set the delay between automatic restarts:
In the configuration file, use restart_ The delay property sets delayed restart.
Prohibit automatic restart
This is useful if we want to run the script once and do not want the process manager to restart our script when the script finishes running.
In the configuration file, use the autorestart: false attribute to disable automatic restart.
Specifies an exit code that does not restart automatically
Sometimes we may want the application to restart automatically in the event of a failure (that is, a non-zero exit code) rather than the process manager to restart it when it closes properly (that is, the exit code is equal to 0).
In this case, PM2 can still be used well and stop_ exit_ The codes option is set to the exit code that should skip automatic restart:
In the configuration file, use stop_ exit_ The codes property sets the exit code without automatic restart.
Exponential backoff restart delay
A new restart mode has been implemented on PM2 Runtime to restart our applications in a more intelligent way. When an exception occurs (such as database shutdown), instead of restarting the application crazily, exponential backoff restart will increase the time between restarts and reduce the pressure on our database or external providers. Very easy to use:
Set this function on the terminal command line with the option — exp backoff restart delay
In the configuration file, use exp_backoff_restart_delay property.
When the application crashes unexpectedly and the option — exp backoff restart delay is activated, we will be able to see the new application state waiting restart.
By running pm2 logs , we will also see an increase in restart latency:
As you can see, the restart delay between restarts will increase exponentially until the maximum value between restarts is 15000 milliseconds.
When the application returns to stable mode (uptime does not exceed 30 seconds), the restart delay will automatically reset to 0 milliseconds.
For more information about pm2, refer to pm2 tutorial
Posted on Mon, 29 Nov 2021 17:52:29 -0500 by The_Stranger
Источник
Name already in use
pm2-hive.github.io / docs / features / restart-strategies.md
- Go to file T
- Go to line L
- Copy path
- Copy permalink
Copy raw contents
Copy raw contents
When starting application with PM2, application are automatically restarted on auto exit, event loop empty (node.js) or when application crash. But you can also configure extra restart strategies like:
- Restart app at a specified CRON time
- Restart app when files have changed
- Restart when app reach a memory threshold
- Delay a start and automatic restart
- Disable auto restart (app are always restarted with PM2) when crashing or exiting by default)
- Restart application automatically at a specific exponential increasing time
Restart at cron time
Via configuration file, use the cron_restart attribute:
To disable cron restart:
Restart on file change
PM2 can automatically restart your application when a file is modified in the current directory or its subdirectories:
Note: If an application is started with the —watch option, stopping the app will not prevent it to be restarted on file change. To totally disable the watch feature, do: pm2 stop app —watch or toggle the watch option on application restart via pm2 restart app —watch .
Via configuration file, use the watch: true attribute:
You can specify which folder to watch for change, ignore folder and watch files interval with these options:
Memory based restart strategy
PM2 allows to reload (auto fallback to restart if not in cluster) an application based on a memory limit/ Please note that the PM2 internal worker (which checks memory), starts every 30 seconds, so you may have to wait a bit before your process gets restarted automatically after reaching the memory threshold.
Via configuration file, use the max_memory_restart attribute:
Note: Units can be K(ilobyte) (e.g. 512K ), M(egabyte) (e.g. 128M ), G(igabyte) (e.g. 1G ).
Set a delay between auto restart with the Restart Delay strategy:
Via configuration file, use the restart_delay attribute:
No Auto Restart
This is useful in case we wish to run 1-time scripts and don’t want the process manager to restart our script in case it’s completed running.
Via configuration file, use the autorestart attribute:
Skip Auto Restart For Specific Exit Codes
Sometimes you might want the application to automatically restart in case of failure (i.e. non-zero exit code), while not wanting the process manager to restart it when it shuts down properly (i.e. exit code equal to 0).
In this case, you can still use PM2 just fine with a stop_exit_codes option set to exit codes that should skip auto restart:
Or via configuration file, use the stop_exit_codes attribute:
Exponential Backoff Restart Delay
A new restart mode has been implemented on PM2 Runtime, making your application restarts in a smarter way. Instead of restarting your application like crazy when exceptions happens (e.g. database is down), the exponential backoff restart will increase incrementally the time between restarts, reducing the pressure on your DB or your external provider. Pretty easy to use:
Via configuration file, use the exp_backoff_restart_delay attribute:
When an application crash unexpectedly and the option —exp-backoff-restart-delay is activated, you will be able to see a new application status waiting restart.
By running pm2 logs you will also see the restart delay being incremented:
As you can see the restart delay between restarts will increase in an exponential moving average, till reaching the maximum of 15000ms between restarts.
When the application will then get back to a stable mode (uptime without restarts of more than 30 seconds), the restart delay will automatically reset to 0ms.
Источник
Restart strategies
When starting application with PM2, application are automatically restarted on auto exit, event loop empty (node.js) or when application crash.
But you can also configure extra restart strategies like:
- Restart app at a specified CRON time
- Restart app when files have changed
- Restart when app reach a memory threshold
- Delay a start and automatic restart
- Disable auto restart (app are always restarted with PM2) when crashing or exiting by default)
- Restart application automatically at a specific exponential increasing time
Restart at cron time
Via CLI:
$ pm2 start app.js --cron-restart="0 0 * * *"
# Or when restarting an app
$ pm2 restart app --cron-restart="0 0 * * *"
Via configuration file, use the cron_restart
attribute:
module.exports = {
apps : [{
name: 'Business News Watcher',
script: 'app.js',
instances: 1,
cron_restart: '0 0 * * *',
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
}
}]
}
To disable cron restart:
pm2 restart app --cron-restart 0
Restart on file change
PM2 can automatically restart your application when a file is modified in the current directory or its subdirectories:
Via CLI:
$ pm2 start app.js --watch
Note: If an application is started with the --watch
option, stopping the app will not prevent it to be restarted on file change.
To totally disable the watch feature, do: pm2 stop app --watch
or toggle the watch option on application restart via pm2 restart app --watch
.
Via configuration file, use the watch: true
attribute:
module.exports = {
script: "app.js",
watch: true
}
You can specify which folder to watch for change, ignore folder and watch files interval with these options:
module.exports = {
script: "app.js",
// Specify which folder to watch
watch: ["server", "client"],
// Specify delay between watch interval
watch_delay: 1000,
// Specify which folder to ignore
ignore_watch : ["node_modules", "client/img"],
}
Memory based restart strategy
PM2 allows to reload (auto fallback to restart if not in cluster) an application based on a memory limit/ Please note that the PM2 internal worker (which checks memory), starts every 30 seconds, so you may have to wait a bit before your process gets restarted automatically after reaching the memory threshold.
CLI:
$ pm2 start api.js --max-memory-restart 300M
Via configuration file, use the max_memory_restart
attribute:
module.exports = {
script: 'api.js',
max_memory_restart: '300M'
}
Note: Units can be K(ilobyte) (e.g. 512K
), M(egabyte) (e.g. 128M
), G(igabyte) (e.g. 1G
).
Restart Delay
Set a delay between auto restart with the Restart Delay strategy:
CLI:
$ pm2 start app.js --restart-delay=3000
Via configuration file, use the restart_delay
attribute:
module.exports = {
script: 'app.js',
restart_delay: 3000
}
No Auto Restart
This is useful in case we wish to run 1-time scripts and don’t want the process manager to restart our script in case it’s completed running.
CLI:
$ pm2 start app.js --no-autorestart
Via configuration file, use the autorestart
attribute:
module.exports = {
script: 'app.js',
autorestart: false
}
Skip Auto Restart For Specific Exit Codes
Sometimes you might want the application to automatically restart in case of failure (i.e. non-zero exit code),
while not wanting the process manager to restart it when it shuts down properly (i.e. exit code equal to 0).
In this case, you can still use PM2 just fine with a stop_exit_codes
option set to exit codes that should skip auto restart:
CLI:
$ pm2 start app.js --stop-exit-codes 0
Or via configuration file, use the stop_exit_codes
attribute:
module.exports = [{
script: 'app.js',
stop_exit_codes: [0]
}]
Exponential Backoff Restart Delay
A new restart mode has been implemented on PM2 Runtime, making your application restarts in a smarter way. Instead of restarting your application like crazy when exceptions happens (e.g. database is down), the exponential backoff restart will increase incrementally the time between restarts, reducing the pressure on your DB or your external provider… Pretty easy to use:
CLI:
$ pm2 start app.js --exp-backoff-restart-delay=100
Via configuration file, use the exp_backoff_restart_delay
attribute:
module.exports = {
script: 'app.js',
exp_backoff_restart_delay: 100
}
When an application crash unexpectedly and the option --exp-backoff-restart-delay
is activated, you will be able to see a new application status waiting restart.
By running pm2 logs
you will also see the restart delay being incremented:
PM2 | App [throw:0] will restart in 100ms
PM2 | App [throw:0] exited with code [1] via signal [SIGINT]
PM2 | App [throw:0] will restart in 150ms
PM2 | App [throw:0] exited with code [1] via signal [SIGINT]
PM2 | App [throw:0] will restart in 225ms
As you can see the restart delay between restarts will increase in an exponential moving average, till reaching the maximum of 15000ms between restarts.
When the application will then get back to a stable mode (uptime without restarts of more than 30 seconds), the restart delay will automatically reset to 0ms.
Contribute to this page
In this article, we are going to learn, about restarting a Node.js application when an uncaught exception happens. For this, we are going to use the pm2 module.
Approach: Let’s see the approach step by step:
- Step 1: Install the pm2 module and use it to start the server.
- Step 2: When an uncaught exception happens, then execute the command process.exit() to stop the server.
- Step 3: Then, pm2 module will automatically start the server again.
process.exit() stop the server and pm2 force it to start. In this way, the server will restart.
Implementation: Below is the step-by-step implementation of the above approach.
Step 1: Initializes NPM: Create and Locate your project folder in the terminal & type the command
npm init -y
It initializes our node application & makes a package.json file.
Step 2: Install Dependencies: Locate your root project directory into the terminal and type the command
npm install express pm2
To install express and pm2 as dependencies inside your project
Step 3: Creating a list of products: Let’s create an array of products and set it to constant products.
const products = [];
Step 4: Creating Routes for the home page and the products page: Let’s create two routes so that users can access the home page and the products page.
app.get('/', (req, res) => { res.send('Hello Geeks!'); }); app.get('/products', (req, res) => { if (products.length === 0) { res.send('No products found!'); process.exit(); } else { res.json(products); } });
Inside the product route, we use process.exit() method to stop the server.
Complete Code:
Javascript
const express = require(
'express'
);
const app = express();
const products = [];
app.get(
'/'
, (req, res) => {
res.send(
'Hello Geeks!'
);
});
app.get(
'/products'
, (req, res) => {
if
(products.length === 0) {
res.send(
'No products found!'
);
process.exit();
}
else
{
res.json(products);
}
});
app.listen(3000, ()=>{
console.log(
'listening on port 3000'
);
});
Steps to run the application: Inside the terminal type the command to run your script ‘app.js’ with pm2.
pm2 start app.js
Output:
Graceful Shutdown
Your applications will restart several times in its lifetime, be it on deployment or, more sadly, if your application crashes.
But on a restart, a user can face two problems:
- a downtime period, your server returning “503 Service Unavailable” responses
- a failed request, if the request was in progress at the time of restart
Downtime periods can be avoided with the pm2 cluster mode and reload action.
Failed requests can be avoided with graceful shutdown and restart. This tutorial introduce you how to implement it.
Graceful Shutdown
In a graceful shutdown, your app must go through 5 steps:
- receives a notification to stop
- asks the load balancer to stop receiving requests
- finishes all ongoing requests
- releases all resources (databases, queues…)
- exits
Let’s say we have the following express app:
const app = express()
const port = process.env.port || 8000
app.get('/', (req, res) => { res.end('Hello world') })
const server = require('http').createServer(app)
server.listen(port, () => {
console.log('Express server listening on port ' + server.address().port)
})
We need first to intercept the SIGINT signal (emitted by pm2 stop
):
const app = express()
const port = process.env.port || 8000
app.get('/', (req, res) => { res.end('Hello world') })
const server = require('http').createServer(app)
server.listen(port, () => {
console.log('Express server listening on port ' + server.address().port)
})
process.on('SIGINT', () => {
console.info('SIGINT signal received.')
})
We then ask HTTP server to stop receiving requests and finish ongoing ones:
const app = express()
const port = process.env.port || 8000
app.get('/', (req, res) => { res.end('Hello world') })
const server = require('http').createServer(app)
server.listen(port, () => {
console.log('Express server listening on port ' + server.address().port)
})
process.on('SIGINT', () => {
console.info('SIGINT signal received.')
// Stops the server from accepting new connections and finishes existing connections.
server.close(function(err) {
if (err) {
console.error(err)
process.exit(1)
}
})
})
At last, we close connection to all resources:
const app = express()
const port = process.env.port || 8000
app.get('/', (req, res) => { res.end('Hello world') })
const server = require('http').createServer(app)
server.listen(port, () => {
console.log('Express server listening on port ' + server.address().port)
})
process.on('SIGINT', () => {
console.info('SIGINT signal received.')
// Stops the server from accepting new connections and finishes existing connections.
server.close(function(err) {
// if error, log and exit with error (1 code)
if (err) {
console.error(err)
process.exit(1)
}
// close your database connection and exit with success (0 code)
// for example with mongoose
mongoose.connection.close(function () {
console.log('Mongoose connection disconnected')
process.exit(0)
})
})
})
Timeout for kill
By default, pm2 waits 1600ms before sending SIGKILL signal if the applications doesn’t exit itself.
You can change this value, in ms, in your ecosystem.config.js:
module.exports = {
apps: [{
name: "app",
script: "./app.js",
kill_timeout: 1600,
}]
}
Windows graceful stop
When signals are not available your process gets killed. In that case, you need to listen for shutdown
events:
process.on('message', (msg) => {
if (msg == 'shutdown') {
console.log('Closing all connections...')
setTimeout(() => {
console.log('Finished closing connections')
process.exit(0)
}, 1500)
}
})
Graceful start
Your application often require to be connected to your database or other resources before serving HTTP requests.
Your app must go through these 3 steps to avoid errors:
- opens DB connections
- starts listening to a port
- notifies pm2 that the application is ready
First, enable the ready
signal in pm2 in your ecosystem.config.js:
module.exports = {
apps : [{
name: "api",
script: "./api.js",
wait_ready: true,
listen_timeout: 3000,
}],
}
By default, after 3000ms, pm2 will consider your app ready. Change this value with the listen_timeout
value.
Let’s keep using the previous express app:
const app = express()
const port = process.env.port || 8000
app.get('/', (req, res) => { res.end('Hello world') })
server.listen(port, () => {
console.log('Express server listening on port ' + server.address().port)
})
...
First, wait for your database connection to be ready:
const app = express()
const port = process.env.port || 8000
app.get('/', (req, res) => { res.end('Hello world') })
const server = require('http').createServer(app)
mongoose.connect('mongodb://mongosA:27501,mongosB:27501', (err) => {
server.listen(port, () => {
console.log('Express server listening on port ' + server.address().port)
})
})
...
At last, notify pm2 that the application is ready with process.send('ready')
:
const app = express()
const port = process.env.port || 8000
app.get('/', (req, res) => { res.end('Hello world') })
const server = require('http').createServer(app)
mongoose.connect('mongodb://mongosA:27501,mongosB:27501', (err) => {
server.listen(port, () => {
console.log('Express server listening on port ' + server.address().port)
process.send('ready')
})
})
...
Graceful start in cluster mode
In cluster mode, there is a default system that sets each cluster ready when the app accepts a connection. There is also a time out, which default to 3000ms, that you can set with the listen_timeout
property in your ecosystem file.
use PM2 launch application When, the application will restart automatically when it exits automatically, the event loop is empty (node.js), or the application crashes. However, you can also configure additional restart policies, such as:
- Restart the application using a scheduled task
- Restart the application after the file changes
- Restart when application reaches memory threshold
- Delayed start and automatic restart
- By default, automatic restart is disabled on crash or exit (applications always restart using PM2)
- Automatically restart applications at specific exponential growth times
Restart the application using a scheduled task
Use the following command to set the task of scheduled restart
$ pm2 start server.js --cron-restart="0 0 * * *" # Or set a scheduled task when restarting $ pm2 restart app --cron-restart="0 0 * * *"
If yes configuration file If so, use cron_restart attribute:
server.config.js
module.exports = { apps : [{ name: 'server', script: 'server.js', instances: 1, cron_restart: '0 0 * * *', env: { NODE_ENV: 'development' }, env_production: { NODE_ENV: 'production' } }] }
Automatically restart the application after file changes
When the files in the current directory or its subdirectory are modified, PM2 can automatically restart your application:
Use the following command to start the application by specifying the option — watch later
$ pm2 start server.js --watch
Let’s illustrate this situation through gif dynamic diagram
Note: if the application starts using the – watch option, stopping the application does not prevent it from restarting when the file changes. To completely disable the watch function, execute the following command:
$ pm2 stop app --watch
Or use the following command to switch the watch option when the application restarts.
$ pm2 restart app --watch
In the configuration file, use the watch: true attribute
module.exports = { script: "server.js", watch: true }
We can also specify which folder to listen to in the configuration file, and automatically restart the application when its contents are modified. You can also specify that some folders are ignored, and no restart will be triggered regardless of how their contents change
module.exports = { script: "server.js", // Specify the folder to listen to watch: ["server", "client"], // Specify delay time watch_delay: 1000, // Specify the folder to ignore ignore_watch : ["node_modules", "client/img"], }
Restart when application reaches memory threshold
PM2 allows applications to be reloaded according to the memory limit (if they are not in the cluster, they will automatically fall back and restart) / please note that PM2 internal working program (check memory) starts every 30 seconds, so it may take a moment after reaching the memory threshold, and the process will restart automatically.
Use the — Max memory restart option to specify the memory threshold.
$ pm2 start server.js --max-memory-restart 300M
Use Max in configuration file_ memory_ Restart attribute.
server.config.js
module.exports = { script: 'server.js', max_memory_restart: '300M' }
Note: the units can be K(ilobyte) (e.g. 512K), m (egabyte) (e.g. 128M), G (igabyte) (e.g. 1G).
Delayed restart
Use the Restart Delay policy to set the delay between automatic restarts:
$ pm2 start server.js --restart-delay=3000
In the configuration file, use restart_ The delay property sets delayed restart.
server.config.js
module.exports = { script: 'server.js', restart_delay: 3000 }
Prohibit automatic restart
This is useful if we want to run the script once and do not want the process manager to restart our script when the script finishes running.
$ pm2 start server.js --no-autorestart
In the configuration file, use the autorestart: false attribute to disable automatic restart.
server.config.js
module.exports = { script: 'server.js', autorestart: false }
Specifies an exit code that does not restart automatically
Sometimes we may want the application to restart automatically in the event of a failure (that is, a non-zero exit code) rather than the process manager to restart it when it closes properly (that is, the exit code is equal to 0).
In this case, PM2 can still be used well and stop_ exit_ The codes option is set to the exit code that should skip automatic restart:
$ pm2 start server.js --stop-exit-codes 0
In the configuration file, use stop_ exit_ The codes property sets the exit code without automatic restart.
server.config.js
module.exports = [{ script: 'server.js', stop_exit_codes: [0] }]
Exponential backoff restart delay
A new restart mode has been implemented on PM2 Runtime to restart our applications in a more intelligent way. When an exception occurs (such as database shutdown), instead of restarting the application crazily, exponential backoff restart will increase the time between restarts and reduce the pressure on our database or external providers… Very easy to use:
Set this function on the terminal command line with the option — exp backoff restart delay
$ pm2 start app.js --exp-backoff-restart-delay=100
In the configuration file, use exp_backoff_restart_delay property.
server.config.js
module.exports = { script: 'server.js', exp_backoff_restart_delay: 100 }
When the application crashes unexpectedly and the option — exp backoff restart delay is activated, we will be able to see the new application state waiting restart.
By running pm2 logs , we will also see an increase in restart latency:
PM2 | App [throw:0] will restart in 100ms PM2 | App [throw:0] exited with code [1] via signal [SIGINT] PM2 | App [throw:0] will restart in 150ms PM2 | App [throw:0] exited with code [1] via signal [SIGINT] PM2 | App [throw:0] will restart in 225ms
As you can see, the restart delay between restarts will increase exponentially until the maximum value between restarts is 15000 milliseconds.
When the application returns to stable mode (uptime does not exceed 30 seconds), the restart delay will automatically reset to 0 milliseconds.
For more information about pm2, refer to pm2 tutorial
Process management refers to various activities around the creation,
termination, and monitoring of processes. A process manager is a program that
ensures that your applications always stay online after being
launched.
Process managers can prevent downtime in production by automatically restarting your
application after a crash or even after the host machine reboots. They are
also useful in development: they auto-restart an app once its source files or
dependencies are updated. Process managers also typically provide monitoring
tools that access application logs and other key metrics, such as CPU and memory
usage.
PM2 is a Node.js process manager that comes
with a built-in load balancer. It helps facilitate production
deployments and enables you to keep running applications alive indefinitely
(even when accidents occur). It also lets you gain insights into your
application’s runtime performance and resource consumption and scale your
application in real-time through its clustering feature.
In this article, we’ll examine PM2’s most important features and discover how it
can help you increase the resilience of your Node.js applications in production.
Getting Started with PM2
PM2 is available as an NPM package, so you
can install it through npm
or yarn
:
$ npm install pm2
# or
$ yarn add pm2
After installing PM2, run npx pm2 --version
to see the installed version:
$ npx pm2 --version
5.1.2
If you don’t want to prefix the pm2
command with npm
every time, you can
install it globally:
$ npm install -g pm2
# or
$ yarn global add pm2
Aside from the main pm2
command, the
installation provides some other executables:
pm2-dev
: a development tool for restarting your application when file
changes in the directory are detected (similar to
Nodemon).pm2-runtime
: designed to be a drop-in replacement for thenode
binary in
Docker containers. It helps keep the running application in the
foreground (unlikepm2
, which sends it to the background) so that the
container keeps running.pm2-docker
: an alias forpm2-runtime
.
Start Your Node.js App in Development Mode with PM2
It can be quite tedious to restart your application server in development every
time you change the source files. Using the pm2-dev
binary to start
your application can take care of that concern automatically:
$ pm2-dev start app.js
===============================================================================
--- PM2 development mode ------------------------------------------------------
Apps started : app
Processes started : 1
Watch and Restart : Enabled
Ignored folder : node_modules
===============================================================================
app-0 | {"level":30,"time":1638512528047,"pid":4575,"hostname":"Kreig","msg":"Server listening at http://127.0.0.1:3000"}
[rundev] App app restarted
app-0 | {"level":30,"time":1638512535737,"pid":4631,"hostname":"Kreig","msg":"Server listening at http://127.0.0.1:3000"}
At this point, your server will auto-restart each time you create, modify or
delete a source file in your project. It also works when you add or
remove a dependency with npm
or yarn
.
Start Your Node.js App in Production Mode with PM2
When deploying an application to production, you can use the pm2
binary to
start it in the background. It launches a daemon that monitors your application
and keeps it running indefinitely.
$ pm2 start app.js
[PM2] Starting /home/ayo/dev/demo/covid-node/app.js in fork_mode (1 instance)
[PM2] Done.
┌─────┬────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├─────┼────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0 │ app │ default │ 1.0.0 │ fork │ 16573 │ 0s │ 0 │ online │ 0% │ 19.1mb │ ayo │ disabled │
└─────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
PM2 defaults to the name of the entry file as the app’s name
, but you can
use a more recognizable name through the --name
option. This name is what
you’ll use to reference the application in many pm2
subcommands.
$ pm2 start app.js --name "my app"
Suppose you need to ensure that your application has established connections with
other services (such as the database or cache) before being considered
«online» by PM2. In that case, you can use the --wait-ready
option when starting your
application. This causes PM2 to wait for 3 seconds (by default) or for a ready event
(process.send('ready')
) before the application is considered ready. You can
use the --listen-timeout
option to change the length of the delay.
$ pm2 start app.js --wait-ready --listen-timeout 5000 # wait for 5 seconds
Monitoring Your Running Applications in PM2
To list your running applications, use the pm2 list
command. This prints a
table describing the state of all running applications with columns for:
- the app name and id
- CPU and memory usage
- number of restarts (
↺
) - uptime
- process id
- the mode (
fork
orcluster
)
and others.
You can use this table alongside a host
monitoring service like AppSignal to give you a complete
picture of your application and its host environment:
$ pm2 list
┌─────┬───────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├─────┼───────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0 │ app │ default │ 1.0.0 │ fork │ 16573 │ 9m │ 0 │ online │ 0% │ 57.3mb │ ayo │ disabled │
│ 2 │ index │ default │ 1.0.0 │ fork │ 0 │ 0 │ 16 │ errored │ 0% │ 0b │ ayo │ disabled │
│ 1 │ server │ default │ 0.1.0 │ fork │ 17471 │ 71s │ 0 │ online │ 0% │ 77.5mb │ ayo │ disabled │
└─────┴───────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
If you see only a subset of this information, try enlarging your terminal
window. The list
subcommand will not display all the columns if your terminal
window is too small. You can also sort the output table according to a metric of
your choice:
$ pm2 list --sort [name|id|pid|memory|cpu|status|uptime][:asc|desc]
# such as
$ pm2 list --sort uptime:desc
If you require more information about a particular app beyond what list
provides, use the show
subcommand and pass the app name to view more
detailed application process metadata. Some of the metrics and data
presented in the output include the app’s:
- output and error log files
- heap size and usage
- event loop latency
- uptime
- number of restarts
- source control metadata
and more.
$ pm2 show server
Describing process with id 1 - name server
┌───────────────────┬──────────────────────────────────────────────────┐
│ status │ online │
│ name │ server │
│ namespace │ default │
│ version │ 0.1.0 │
│ restarts │ 0 │
│ uptime │ 60m │
│ script path │ /home/ayo/dev/demo/analytics-dashboard/server.js │
│ script args │ N/A │
│ error log path │ /home/ayo/.pm2/logs/server-error.log │
│ out log path │ /home/ayo/.pm2/logs/server-out.log │
│ pid path │ /home/ayo/.pm2/pids/server-1.pid │
│ interpreter │ node │
│ interpreter args │ N/A │
│ script id │ 1 │
│ exec cwd │ /home/ayo/dev/demo/analytics-dashboard │
│ exec mode │ fork_mode │
│ node.js version │ 17.0.0 │
│ node env │ N/A │
│ watch & reload │ ✘ │
│ unstable restarts │ 0 │
│ created at │ 2021-12-03T08:33:01.489Z │
└───────────────────┴──────────────────────────────────────────────────┘
. . .
Another way to keep tabs on your running applications is through the built-in
terminal dashboard (accessed through the monit
subcommand). This allows
you to view live data on resource usage and logs for each of your applications.
Restarting Your Node.js Application with PM2
PM2 allows you to configure several different strategies for how your
Node.js application should restart. By default, it restarts your application if it exits
or crashes to minimize the impact to your customers in production while the
source of the crash is investigated. The restart
subcommand is also
available for manually restarting your application at any time.
To ensure a graceful shutdown, make sure you intercept the SIGINT
signal to
stop all new requests and finish up existing ones before allowing your program
to exit.
process.on('SIGINT', function() {
gracefulShutdown((err) => {
process.exit(err ? 1 : 0)
});
})
You can use the --kill-timeout
option to ensure that a graceful shutdown does
not take too long:
$ pm2 restart app --kill-timeout 5000 # set a 5 second limit
Auto Restart Based on Memory Usage
The --max-memory-restart
option is available to restart an app when it
reaches a certain memory threshold. This can help prevent a Node.js heap out of
memory error. You can specify the memory limit in kilobytes
(K
), Megabytes (M
), or Gigabytes (G
).
$ pm2 start app.js --max-memory-restart 1G
Auto Restart Based on Cron Schedule
PM2 also offers a restart strategy based on the Cron
syntax.
This allows you to schedule a restart at a specific time each day / on certain days of the
week / a set time interval (such as every 48 hours).
# Restart at 12:00 pm every day
$ pm2 start app.js --cron-restart="0 12 * * *"
Auto Restart on File Change
Remember how pm2-dev
auto-restarts your application when you make changes to a file? You can
configure the pm2
command to act in a similar manner through the --watch
subcommand. In the table outputted by pm2 list
, look at the watching
column to observe the watch
status of an application.
$ pm2 start app.js --watch
Auto Restart after a Delay
You can configure the --restart-delay
option to set a delay for automatic
restarts. The delay should be supplied in milliseconds.
$ pm2 start app.js --restart-delay=5000 # 5s delay
Ignore Some Exit Codes When Auto Restarting
PM2 auto-restarts your app when the process exits, but it does not take the exit
code into account by default, so it
restarts regardless of whether the app exits cleanly or crashes. If this
behavior is not desired, you can use the --stop-exit-codes
option to set exit
codes that should not prompt PM2 to auto-restart. For example, you can ensure
PM2 does not auto-restart on a clean exit with the following command:
$ pm2 start app.js --stop-exit-codes 0
Restarting Processes after a System Reboot
The previous section covered a variety of ways to restart your application after
it is launched. However, none of the strategies there will keep
your application up if your server reboots. Notably, PM2 ships with a
startup feature that can help solve
this problem. You can combine this with a good uptime monitoring
service like AppSignal’s to guarantee that
your application comes back online quickly, even if an accident happens.
You’ll need to generate a startup script for your server’s init system to execute on system boot and launch the PM2 process, which will
subsequently start the configured application processes immediately. You can
allow PM2 to autodetect your startup script or pass the init system used by
your operating system, which could be systemd
, upstart
, launchd
, rcd
, or
systemv
.
$ pm2 startup # autodetect init system
# or
$ pm2 startup systemd # generate script for systemd
You should receive the following output:
[PM2] Init System found: systemd
-----------------------------------------------------------
PM2 detected systemd but you precised systemd
Please verify that your choice is indeed your init system
If you arent sure, just run : pm2 startup
-----------------------------------------------------------
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u ayo --hp /home/ayo
You’ll need to copy and paste the generated command into the terminal, and then
run it as the root:
$ sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup <distribution> -u <user> --hp <home-path>
If everything goes well, you’ll see the following output, indicating that
PM2 is configured to start at boot.
[PM2] Init System found: systemd
. . .
[PM2] [v] Command successfully executed.
+---------------------------------------+
[PM2] Freeze a process list on reboot via:
$ pm2 save
[PM2] Remove init script via:
$ pm2 unstartup systemd
At this point, you can run pm2 save
to save your process list. This saves the
processes currently managed by PM2 to disk so they’re accessible to the
daemon on system boot.
$ pm2 save
[PM2] Saving current process list...
[PM2] Successfully saved in /home/<user>/.pm2/dump.pm2
Go ahead and restart your computer or server. Once it boots back up, run
pm2 list
to see if all the processes are restored. If PM2 doesn’t restore
them automatically, you can manually relaunch them with the resurrect
subcommand. You then won’t need to start each process individually.
$ pm2 resurrect
[PM2] Resurrecting
[PM2] Restoring processes located in /home/<user>/.pm2/dump.pm2
At any point in the future, you can run pm2 save
again to update the list of
processes that should be restored on boot or when using the resurrect
subcommand.
Clustering with PM2
Clustering in
Node.js
refers to creating child processes that run
simultaneously and share the same port in an application. This technique makes it possible to
horizontally scale a Node.js application on a single machine, taking advantage
of the processing capabilities offered by multi-core systems (since an instance
of a Node.js app only runs on a single thread).
The
standard Node.js library provides a cluster module to set up clustering in Node.js applications. In a
nutshell, it creates child processes (workers) and distributes incoming
connections across the simultaneously running worker processes. You’ll need to
modify your source code to spawn and manage the workers and
set up how you’d like to distribute incoming connections amongst them.
PM2 also provides a cluster mode that uses the native cluster module under the
hood. However, it does not require any modifications to the application’s source
code. Instead, all you need to do to start a Node.js program in cluster mode is
to supply the -i
option to the start
subcommand, as follows:
$ pm2 start app.js -i 0
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name │ mode │ ↺ │ status │ cpu │ memory │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 0 │ app │ cluster │ 0 │ online │ 0% │ 49.0mb │
│ 1 │ app │ cluster │ 0 │ online │ 0% │ 46.8mb │
│ 2 │ app │ cluster │ 0 │ online │ 0% │ 44.8mb │
│ 3 │ app │ cluster │ 0 │ online │ 0% │ 42.2mb │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
The -i
or instances option above allows you to specify the number of workers
(child processes) that PM2 should launch. You can set 0
or max
to specify that PM2 should spawn as many workers as the number of available CPU
cores (as above). Alternatively, you can set the exact number of workers to be
greater than the number of available CPU cores, if desired. If you want to add
additional worker processes on the fly, use the scale
subcommand as shown
below:
$ pm2 scale <app_name> +4 # add 4 additional workers in realtime
Once your application launches in cluster mode, incoming requests to the
server will be automatically load-balanced across all the worker processes, which
can significantly improve throughput. This feature also enables you to restart
your app in production (using pm2 restart
) without suffering any downtime
since PM2 waits for the new workers to become operational before it kills the
old ones.
PM2’s clustering feature works best when your application is completely
stateless. You won’t need any code
modifications to scale on the same server or even across multiple servers if
your app doesn’t maintain any state in individual processes. If your application
isn’t stateless, you’ll likely get better results directly using the native cluster
module.
Log Management in PM2
Log management is quite straightforward in PM2. The logs for all your running
applications are placed in the ~/.pm2/logs
directory, and they can be
displayed with the logs
subcommand. All log entries are prefixed with the application’s name to ensure easy identification.
$ pm2 logs # display all logs in realtime
$ pm2 logs <app_name> # display only a specific app's logs
You can also clear log data with the flush
subcommand:
$ pm2 flush # clear all log data
$ pm2 flush <app_name> # flush log data for a specific app
To enable log rotation, install the following module:
$ pm2 install pm2-logrotate
Wrap Up and Next Steps: Dive Further into PM2
I hope this article has helped to crystallize the importance of process
management in Node.js applications and how to leverage PM2’s robust feature set
to manage your application efficiently.
PM2 offers other capabilities that were
not covered in this article such as Docker integration, a JavaScript API, and a
daemon-less mode, so ensure you check out
PM2’s documentation to learn more
about these advanced features.
Thanks for reading, and happy coding!
P.S. If you liked this post, subscribe to our JavaScript Sorcery list for a monthly deep dive into more magical JavaScript tips and tricks.
P.P.S. If you need an APM for your Node.js app, go and check out the AppSignal APM for Node.js.