Pm2 перезапуск при ошибке

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

I have a Node.js app ready which is workable, but has known and unknown bugs which crash the app. In such cases it would be nice if pm2 can restart the node app. Is this feature already available in pm2?

asked Oct 1, 2014 at 6:29

Talespin_Kit's user avatar

Talespin_KitTalespin_Kit

20.6k29 gold badges89 silver badges131 bronze badges

Yes, it does this by default. For more information see Restart strategies.

If the app repeatedly fails to start over a short period of time, pm2 may cease restarting. See configuration, min_uptime and max_restarts.

answered Oct 1, 2014 at 6:57

jgillich's user avatar

14

Also, check this new excellent option:

--exp-backoff-restart-delay=100

pm2 will restart the crashed app after 100 milliseconds (0.1 seconds), then step-by-step increase restart-delay to 15 seconds.

answered May 7, 2019 at 12:55

xoid's user avatar

xoidxoid

1,1041 gold badge10 silver badges24 bronze badges

To make app restart when it crashes you have to use one of PM2’s restart strategies.

There is something called «Exponential Backoff Restart Delay» which PM2 explains as:

Instead of restarting your application like crazy when exceptions happens (e.g. database is down), the exponential backoff restart will increase incrementaly the time between restarts.

You can set it using the CLI like this:

pm2 start app.js --exp-backoff-restart-delay=100

There are other restart methods also, which are mentioned here.

answered Mar 24, 2020 at 10:14

illiteratewriter's user avatar

illiteratewriterilliteratewriter

4,0951 gold badge22 silver badges43 bronze badges

This may help:

# Generate Startup Script
$ pm2 startup

# Freeze your process list across server restart
$ pm2 save

# Remove Startup Script
$ pm2 unstartup

More details here

answered Oct 9, 2019 at 14:48

Alliswell's user avatar

AlliswellAlliswell

1,51320 silver badges35 bronze badges

Exponential Backoff Restart Delay

Available in PM2 >= 3.2

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 incrementaly 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

Or via ecosystem.config.js file:

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.

Fixed Restart Delay

Available in PM2 >= 0.9

You can also use the restart_delay to set a fixed timing between restarts:

CLI:

$ pm2 start app.js --restart-delay=3000

Or via ecosystem.config.js file:

module.exports = [{
  script: 'app.js',
  restart_delay: 3000
}]

Memory based reload strategy

Checkout https://pm2.io/docs/docs/runtime/features/memory-limit/

0second Downtime Reload

Checkout the cluster mode to get this behavior

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.

Simply running these scripts from bash would terminate the script in case the ssh-session is terminated and the script should not get restarted when it completes execution.

PM2 is perfect for such cases, providing robust monitoring and logging

CLI:

$ pm2 start app.js --no-autorestart

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:

Last Updated :
18 Jul, 2022

Like Article

Save Article

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

Exponential Backoff Restart Delay

Available in PM2 >= 3.2

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 incrementaly 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

Or via ecosystem.config.js file:

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.

Fixed Restart Delay

Available in PM2 >= 0.9

You can also use the restart_delay to set a fixed timing between restarts:

CLI:

$ pm2 start app.js --restart-delay=3000

Or via ecosystem.config.js file:

module.exports = [{
  script: 'app.js',
  restart_delay: 3000
}]

Memory based reload strategy

Checkout https://pm2.io/docs/docs/runtime/features/memory-limit/

0second Downtime Reload

Checkout the cluster mode to get this behavior

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.

Simply running these scripts from bash would terminate the script in case the ssh-session is terminated and the script should not get restarted when it completes execution.

PM2 is perfect for such cases, providing robust monitoring and logging

CLI:

$ pm2 start app.js --no-autorestart

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

Для обеспечения непрерывной работоспособности Node.js сервера нужно либо постоянно держать открытой консоль, либо использовать менеджер процессов pm2. Он имеет встроенный балансировщик нагрузки, позволяет следить за потребляемыми ресурсами запущенных процессов, автоматически перезапускать процессы после системного сбоя и т. д.

Менеджер процессов pm2 имеется в репозитории npm и должен быть установлен в системе глобально.

Управление процессами¶

Запуск Node.js сервера с использованием pm2 осуществляется командой start, которой передается путь к главному файлу приложения.

Команда start инициирует запуск приложения в фоновом режиме и добавляет его в список процессов, который можно увидеть выполнив команду ls.

Перечень полей таблицы:

  • app name — имя приложения (по умолчанию имя главного файла без расширения), для задания собственного названия используйте при запуске параметр --name: pm2 start app.js --name=custom_app_name
  • id — уникальный идентификатор приложения;
  • mode — режим, в котором был запущен сервер (fork или cluster);
  • pid — уникальный идентификатор процесса в системе;
  • status — статус приложения, может быть launching, online, errored или stopped;
  • restart — количество перезапусков;
  • uptime — время, прошедшее с момента запуска приложения;
  • cpu — нагрузка на процессор в процентах;
  • mem — занимаемая приложением оперативная память.

Для получения более подробной информации о количестве запросов, параметрах запуска процессов и т. д. используйте команду monit.

За перезапуск процесса отвечает команда restart, принимающая имя или идентификатор приложения.

Выполнение restart увеличивает значение одноименного поля в списке процессов применительно к тому из них, для которого была выполнена команда.

Остановка процесса осуществляется командой stop, которой необходимо указать либо название, либо идентификатор приложения.

Выполнение stop останавливает работу приложения, но не удаляет его из списка процессов, статус при этом будет stopped.

Чтобы остановить процесс и удалить его из списка, используйте команду delete.

Посмотреть консольные логи приложения можно командой log. Если для log не указать приложение, то будут выведены логи всех процессов, отсортированные по времени.

Командам restart, stop, delete и log можно передать через пробел сразу несколько процессов для обработки.

pm2 delete app1 app2 app3

Для возможности восстановления и запуска списка процессов в случае перезапуска или непредвиденного сбоя сервера, сохраните текущую конфигурацию на диск выполнив команду save.

После этого сохраненные процессы могут быть запущены следующим образом.

Распределение нагрузки (кластеризация)¶

Запуск приложения в нескольких экземплярах, которые будут распределять между собой поступающие запросы, осуществляется с использованием параметра -i (instances) у команды start, с помощью которого указывается, сколько экземпляров запустить. Создание дополнительных процессов одного и того же приложения называется кластеризацией.

Приведенная команды запускает приложение в двух экземплярах. Помните, что для эффективной работы кластера количество дополнительных процессов не должно превышать количество ядер процессора. Чтобы запустить количество процессов равное количеству ядер, укажите параметру -i значение max.

В данном случае Node.js pm2 самостоятельно определит количество ядер процессора и создаст соответствующее количество дополнительных экземпляров.

Файл ecosystem.config.js¶

Если разработанная вами система состоит из множества приложений, которым к тому же при запуске необходимо указывать массу параметров, то при развертывании на разных серверах этот процесс займет немало времени. Чтобы оптимизировать все это, в pm2 имеется поддержка запуска приложений из конфигурационного файла — ecosystem.config.js.

Чтобы сгенерировать шаблон ecosystem.config.js воспользуйтесь следующей командой.

Теперь в директории, откуда была выполнена команда, должен появиться файл ecosystem.config.js с таким содержимым.

ecosystem.config.js

module.exports = {
  apps: [
    {
      name: 'app',
      script: './app.js',
      env: {
        NODE_ENV: 'development',
      },
      env_production: {
        NODE_ENV: 'production',
      },
    },
  ],
};

В массиве apps каждый элемент является объектом, описывающим конфигурацию для запуска одного приложения набором параметров. Рассмотрим основные из них:

  • name — имя приложения, которое будет отображаться в списке процессов при выполнении команды pm2 list;
  • script — путь к главному файлу приложения, который отвечает за запуск;
  • instances — запускает процесс в кластерном режиме, в качестве значения передается количество дополнительных экземпляров;
  • disable_logs — если задать true, то логи вестись не будут;
  • env — значение переменной среды окружения NODE_ENV в режиме разработки;
  • env_production — значение переменной среды окружения NODE_ENV в режиме эксплуатации.

ПС полным списком параметров можно ознакомиться в официальной документации.

Для запуска описанных в ecosystem.config.js приложений, выполните команду start с указанием пути к файлу.

pm2 start ecosystem.config.js

Если вам нужно запустить только одно приложение из описанного массива, укажите параметр --only и значение поля name из конфигурации.

pm2 start ecosystem.config.js --only my-app

Лимит использования RAM¶

Менеджер процессов Node.js pm2 позволяет настроить перезапуск процесса по достижению использования им указанного объема оперативной памяти. Для этого при запуске приложения необходимо указать параметр --max-memory-restart.

pm2 start index.js --max-memory-restart 150M

Значение параметра указывается в одном из трех возможных измерений:

  • K (килобайты);
  • M (мегабайты)
  • G (гигабайты).

Проверка использования процессами оперативной памяти осуществляется pm2 раз в 30 секунд.

Детектирование изменений¶

В pm2 также можно настроить автоматический перезапуск приложения при изменении одного из его файлов. Для этого при старте приложения укажите параметр --watch.

pm2 start index.js --watch

Процесс отслеживания изменений не завершается с остановкой процесса приложения. Чтобы отключить его, при выполнении команды stop также необходимо передать параметр --watch.

Параметр --watch имеет ряд параметров, но их указание возможно только через файл ecosystem.config.js.

ecosystem.config.js

module.exports = {
  apps: [
    {
      name: 'my-app',
      script: './index.js',
      watch: ['server'],
      ignore_watch: ['node_modules', 'client'],
      watch_delay: 1000,
    },
  ],
};

Здесь в параметре watch явно указывается, изменений каких директорий необходимо отслеживать. Чтобы исключить из отслеживания определенные директории, имеется параметр ignore_watch. А с помощью watch_delay указывается время в миллисекундах, которое необходимо выждать при перезапуске приложения, прежде чем инициировать процесс детектирования изменений.

Буквально пару часов назад у меня завязался спор на тему того, что Node.JS слишком медленная для крупных проектов и ей стоит предпочесть Golang, Rust, PHP, etc. Основным аргументом противоположной стороны в этом споре был факт однопоточности JavaScript. Якобы при разработке приложения производительность просто упрётся в эту однопоточность и ничего сделать уже нельзя — только переписать на каком-то другом языке. Однако дела с этим в NodeJS обстоят немного лучше, чем кажется на первый взгляд. Перед тем, как мы углубимся в эту тему хочу заявить, что уважаю право каждого разработчика использовать тот язык программирования, который пришёлся ему по душе и который он считает предпочтительным в той или иной задаче.

Сделав поиск по ключевому слову «PM2» на Хабре я не нашёл ни одной статьи, посвящённой этому process-менеджеру. Лишь одиночные упоминания в статьях других пользователей. Я загорелся (сильно сказано) идеей наверстать упущенное и пролить свет на этот тёмный уголок разработки backend на Node.JS (о котором многие знают, да, я в курсе). Всех заинтересовавшихся прошу под кат.

PM2 — это менеджер процессов с открытым исходным кодом, распространяющийся под лицензией AGPL-3.0. В момент написания статьи имеет ~350k загрузок в неделю, согласно данным NPM. В основном применяется в средах, где необходимо запустить приложение на NodeJS и забыть о нём (с остальными языками тоже можно использовать, но об этом позднее), позволяющий кластеризировать приложение и гибко распределять нагрузку между ядрами процессора. Небольшая вырезка из репозитория PM2 на GitHub:

PM2 is a production process manager for Node.js applications with a built-in load balancer. It allows you to keep applications alive forever, to reload them without downtime and to facilitate common system admin tasks.

Многие новички при разработке сталкиваются с проблемой, когда после «выкатки» приложения на production сервер, не знают как запустить его «навечно». Пишут в SSH-консоли set NODE_ENV=production && node app.js, всё отлично, приложение работает. Закрывают консоль и приложение больше не работает. Вопрос на StackOverflow — How to run node.js application permanently? набрал более 237 тыс. просмотров за всё время.

PM2 решает эту проблему одной командой:

pm2 start app.js

Эта команда «демонизирует» (от англ. «daemonize») процесс NodeJS, следит за потреблением им памяти и считает нагрузку на процессор.

Вернёмся к нашим баранам

С ростом нагрузки на backend возникает необходимость его масштабирования — как вертикального, так и горизонтального — кому что удобнее в сложившихся обстоятельствах. Как мы знаем, один процесс может использовать несколько ядер процессора, но только в том случае, если внутри процесса имеется несколько потоков. В NodeJS приложениях поток — один. PM2 способен выручить в этой ситуации и распределить нагрузку между несколькими ядрами процессора. По-прежнему всего с одной командой:

pm2 start app.js -i max

В данном случае параметр max соответствует количеству ядер процессора. Т.е. для 8-ядерного процессора будет создано 8 отдельных процессов. Можно также вместо max задать значение -1 и тогда количество процессов будет соответствовать количество_ядер минус 1. Вся прелесть заключается в том, что и HTTP(S)/Websocket/TCP/UDP соединения будут равномерно распределены между этими процессами. Ну чем не горизонтальное масштабирование? Почитать подробнее о кластеризации в PM2 можно по ссылке — PM2 Cluster Mode.

cluster_mode

Вы можете запустить сколько угодно процессов, но всё же рекомендуется придерживаться рекомендации «один процесс на одно ядро».

Бережное отношение к памяти

При разработке на PHP я однажды столкнулся с проблемой. По неопытности неосознанно заложил в движок системы баг, из-за которого при определённых условиях процессы начинали поедать слишком много оперативной памяти. Вдобавок к этому нагружался процессор, из-за чего виртуальная машина просто зависла и у меня не было к ней доступа совсем.
Как знают PHP-разработчики, в PHP-FPM можно задать тип распределения процессов (если вы вдруг не знали, то в PHP-FPM для каждого нового запроса создаётся новый процесс) — статический, когда задаётся минимальный и максимальный порог, и динамический — выделение сколь угодно большого количества процессов, по необходимости. Что будет в PM2, если запустить 8 процессов и все они начнут потреблять много памяти? И эту проблему PM2 в состоянии решить — лишь одним параметром в командной строке:

# Set memory threshold for app reload
pm2 start app.js -i max --max-memory-restart <200MB>

Каждый раз при достижении лимита по памяти PM2 автоматически перезапустит процесс. Распределять память проще чем процессы, не так ли? 8 процессов * 200 мегабайт = 1,6 гигабайт. Математика уровня второго класса.

Помимо перезапуска процесса можно также настроить и перезапуск через N интервал времени. Я пока не придумал в каких случаях это может пригодиться, но не стесняйтесь указать мне на пару примеров в комментариях :)

А если я перезагружу виртуальную машину?

Сюрприз-сюрприз! Эту проблему PM2 тоже решает за вас. Всё ещё не более чем одной единственной командой в консоли:

pm2 startup

PM2 сгенерирует скрипт, который будет поднимать все необходимые процессы при запуске операционной системы. Однако здесь стоит быть бдительным — при обновлении версии Node.JS всё может сломаться. Во избежание этого, после успешного обновления до новой версии Node.JS выполните pm2 unstartup и pm2 startup. Подробнее об этом можно ознакомиться по ссылке — PM2 Startup Script Generator.

А надо ли перезапускать кластеры вручную при внесении изменений?

Конечно же нет! Ну, точнее, вы, конечно, можете перезапускать приложение вручную, но зачем? Автоматизируйте всё что можете и да прибудет с вами сила!

pm2 start env.js --watch --ignore-watch="node_modules"

Вы можете пользоваться этим при слиянии master-ветки в локальном репозитории с master-веткой из удалённого репозитория. В моём сайд-проекте это делается просто — git pull origin master && npm run build. При изменении файлов в папках server/build и client/build процессы будут автоматически перезапущены. Я понимаю, это очень простенькая фича и она не заслуживает даже быть упомянутой в этом тексте. Разбавлю его кое-чем серьёзным и напишу о том, что если вы пользуетесь кластеризацией, то все процессы будут перезагружены поочерёдно. Да так, что как минимум один из них будет всегда доступен. Это же zero-downtime deployment!

А можно и не перезапускать процессы. Для этого есть reload (нечто похожее на nginx reload):

pm2 reload all

Слишком много команд! И вообще я предпочитаю конфиги

Мне уже наскучило придумывать весёлые фразы, поэтому просто и банально: файл экосистемы — есть. Поддерживаются форматы JSON, YAML и JS. Например, когда необходимо следить за файлами в папках server и client:

module.exports = {
  apps: [{
    script: "app.js",
    watch: ["server", "client"],
    env_production : {
      "NODE_ENV": "production"
    }
  }]
}

Подробнее ознакомиться можно по ссылке — PM2 Application Declaration.

И даже мониторинг есть!

И не один. Выбирайте тот который нравится больше. Можно мониторить в консоли командой:

pm2 monit

Или же воспользоваться полноценной веб-версией мониторинга:

Вы мне, конечно же, не поверите, но она устанавливается и запускается одной командой:

pm2 plus

И многое-многое другое…

Заявлена поддержка Heroku и Docker, автоматическое инкрементирование портов с возможностью передачи в process.env (когда нужно каждый процесс запускать на отдельном порту), запуск нескольких инстансов PM2 в пределах одной ОС, наличие программного API и возможность запускать демонизированные Bash и Python скрипты!

Вероятно, я упустил ещё что-то важное или интересное, о чём всегда можно напомнить мне в комментариях. Надеюсь, что вы смогли почерпнуть для себя что-то новое из этой статьи.

В этой статье я расскажу о самом удобном, на мой взгляд, диспетчере процессов. Покажу, как его установить и настроить свои проекты (например: скрипт для автопостинга, сервис на ReactJS). 

PM2 запускает приложения и скрипты в режиме 24/7 и решает проблему с их вылетами путем автоматического перезапуска с сохранением лога. Это решение особенно полезно для тех, кто держит на своем сервере большое количество скриптов и нуждается в их удобном управлении.

Рассмотрим установку и настройку на примере Ubuntu 18.04.

Установка

Так как PM2 написан на Node.js и устанавливается с помощью npm, нужно установить их на свой виртуальный сервер:

sudo apt install nodejs

​sudo apt install npm

Теперь устанавливаем сам диспетчер процессов:

Готово! PM2 на сервере.

Комьюнити теперь в Телеграм

Подпишитесь и будьте в курсе последних IT-новостей

Подписаться

Настройка

PM2 в основном предназначен для приложений Node.js, но работает и с остальными языками программирования. Чтобы запустить приложение, используем команды в консоли.

Для Node.js:

Для остальных языков программирования (на примере Python 3):

pm2 start app_name.py --interpreter=python3

Если ваше приложение завершит работу с ошибкой, PM2 автоматически перезапустит его, что очень удобно.

После запуска скриптов и приложений можно посмотреть информацию о них с помощью команды в консоли:

Пример того, что мы увидим:

pm2 list

В таблице показано количество рестартов, потребляемая память и нагрузка на процессор от приложений.

Для удаления, запуска, рестарта и остановки приложений из списка нужно посмотреть порядковый номер (id) процесса в таблице, которую можно вызвать командой, указанной выше, и написать команды в консоли.

Остановка:

pm2 stop id

Запуск:

pm2 start id

Рестарт:

pm2 restart id

Удаление из списка:

pm2 delete id

Также можно просмотреть логи отдельных приложений. Для этого используем эту команду:

И выбираем свое приложение из списка.

pm2 monitЕсли вам неудобно следить за логами и запуском приложений через консоль, то это можно делать даже в браузере, установив веб-версию PM2 одной командой:

После этого вводим свои данные для регистрации и переходим по ссылке, которая отобразится в консоли.

Пример того, что мы увидим:

pm2 plusМы разобрали основные команды менеджера процессов. Удачи в ваших проектах!

VDS Timeweb арендовать

Понравилась статья? Поделить с друзьями:
  • Pluto b46 v2 ошибки
  • Plugin command контур ошибка
  • Pls input pwd ошибка терминала s90
  • Playstation произошла ошибка e 8210604a
  • Playstation ошибка su 30746 0