Введение: Зачем нужна настройка PM2?
Представь, что твое Node.js приложение работает на продакшн-сервере и внезапно падает посреди ночи. Без надлежащего менеджера процессов это означает простой, потерянные данные и срочные звонки. PM2 решает эту проблему, превращая обычный скрипт в надежную, самовосстанавливающуюся службу. Давай разберем, как правильно настроить PM2 для профессиональной эксплуатации.
Установка и базовая настройка PM2
Начнем с установки PM2 глобально через npm:
npm install pm2 -g
# Проверяем установку
pm2 --version
Запуск приложения
Самый простой способ запустить приложение:
# Запуск простого приложения
pm2 start app.js
# Запуск с именем процесса
pm2 start app.js --name "my-app"
# Запуск с автоматическим перезапуском при изменениях (для разработки)
pm2 start app.js --watch
Конфигурация через ecosystem.config.js
Для продвинутой настройки создаем файл конфигурации:
module.exports = {
apps: [{
name: "my-production-app",
script: "./dist/server.js",
instances: "max", // Использовать все CPU ядра
exec_mode: "cluster", // Режим кластера
env: {
NODE_ENV: "development",
},
env_production: {
NODE_ENV: "production",
},
// Логирование
error_file: "./logs/err.log",
out_file: "./logs/out.log",
log_file: "./logs/combined.log",
time: true, // Добавлять timestamp в логи
// Автоматический перезапуск
max_restarts: 10, // Максимум перезапусков
min_uptime: "5s", // Минимальное время работы
// Мониторинг ресурсов
max_memory_restart: "1G", // Перезапуск при превышении памяти
// Перезагрузка при изменениях (только для разработки)
watch: false,
ignore_watch: [
"node_modules",
"logs",
".git"
],
// Переменные окружения
env: {
PORT: 3000,
DATABASE_URL: "postgres://user:pass@localhost/db"
}
}]
};
Запуск с конфигурацией
# Запуск с конфигурацией
pm2 start ecosystem.config.js
# Запуск с продакшн окружением
pm2 start ecosystem.config.js --env production
# Перезапуск всех процессов
pm2 restart ecosystem.config.js
Кластеризация и балансировка нагрузки
PM2 позволяет легко настроить кластеризацию для использования всех ядер CPU:
module.exports = {
apps: [{
name: "api-cluster",
script: "./server.js",
instances: 4, // Запустить 4 инстанса
exec_mode: "cluster", // Включить режим кластера
// Настройки балансировки
listen_timeout: 50000, // Таймаут для graceful shutdown
kill_timeout: 5000, // Время на graceful shutdown
// Автомасштабирование
max_restarts: 10,
min_uptime: "10s"
}]
};
Полезные команды для управления кластером
# Показать все процессы
pm2 list
# Мониторинг в реальном времени
pm2 monit
# Показать логи конкретного приложения
pm2 logs my-app
# Перезагрузить приложение (graceful restart)
pm2 reload my-app
# Масштабировать кластер
pm2 scale my-app +2 # Добавить 2 инстанса
pm2 scale my-app 4 # Установить ровно 4 инстанса
# Остановить все процессы
pm2 stop all
# Удалить все процессы из списка
pm2 delete all
Настройка логирования
Правильная настройка логов критически важна для отладки:
module.exports = {
apps: [{
name: "app-with-logs",
script: "./app.js",
// Раздельные логи для ошибок и вывода
error_file: "/var/log/pm2/app-error.log",
out_file: "/var/log/pm2/app-out.log",
// Комбинированный лог
log_file: "/var/log/pm2/app-combined.log",
// Формат логов
time: true, // Добавлять дату/время
log_date_format: "YYYY-MM-DD HH:mm Z",
// Ротация логов
merge_logs: true, // Объединять логи всех инстансов
// Максимальный размер файла перед ротацией
max_size: "10M",
// Количество файлов для хранения
retain: 5
}]
};
Управление логами через CLI
# Показать последние 100 строк логов
pm2 logs my-app --lines 100
# Показать логи в реальном времени
pm2 logs my-app
# Очистить все логи
pm2 flush
# Экспорт логов в файл
pm2 logs my-app --json > logs.json
# Мониторинг с фильтрацией
pm2 logs my-app --error # Только ошибки
Автозагрузка PM2 при старте системы
Чтобы приложения запускались автоматически после перезагрузки сервера:
# Для систем с systemd (Ubuntu 16+, Debian 8+, CentOS 7+)
pm2 startup systemd
# Для старых систем с init.d
pm2 startup ubuntu
# Сохранить текущую конфигурацию для автозагрузки
pm2 save
# Показать сценарий автозагрузки
pm2 startup
# Удалить автозагрузку
pm2 unstartup
pm2 startup скопируйте и выполните предложенную команду от суперпользователя. Затем выполните pm2 save чтобы сохранить текущий список процессов.
Мониторинг и метрики
PM2 предоставляет встроенные инструменты мониторинга:
# Запустить веб-интерфейс мониторинга (порт 9615)
pm2 plus
# Альтернатива: встроенный монитор
pm2 monit
# Показать метрики в реальном времени
pm2 show [app-name]
# Экспорт метрик в формате JSON
pm2 jlist
# Проверка здоровья приложения
pm2 ping
Настройка PM2 Plus для продвинутого мониторинга
Для использования PM2 Plus (ранее Keymetrics) потребуется токен:
# Подключение к PM2 Plus
pm2 link [секретный_ключ] [публичный_ключ] [имя_сервера]
# Отключение от PM2 Plus
pm2 unlink
# Обновить метаданные сервера
pm2 update
Сравнение режимов работы PM2
| Режим | Описание | Использование CPU | Когда использовать |
|---|---|---|---|
fork |
Один процесс, без кластеризации | 1 ядро | Разработка, тестирование |
cluster |
Множество процессов, балансировка нагрузки | Все ядра | Продакшн, высоконагруженные приложения |
max |
Автоматическое определение числа инстансов | Оптимально | Когда не знаешь точное число ядер |
Продвинутые настройки и оптимизация
Настройка переменных окружения
module.exports = {
apps: [{
name: "app-env",
script: "./app.js",
// Разные окружения
env: {
NODE_ENV: "development",
PORT: 3000,
API_KEY: "dev-key"
},
env_staging: {
NODE_ENV: "staging",
PORT: 4000,
API_KEY: "staging-key"
},
env_production: {
NODE_ENV: "production",
PORT: 80,
API_KEY: "prod-key-12345",
// Безопасное хранение секретов
DATABASE_URL: process.env.DATABASE_URL
}
}]
};
Graceful Shutdown и Health Checks
module.exports = {
apps: [{
name: "graceful-app",
script: "./app.js",
// Настройки graceful shutdown
kill_timeout: 3000, // 3 секунды на завершение
listen_timeout: 50000, // Таймаут для запуска
shutdown_with_message: true,
// Health check
health_check: {
url: "http://localhost:3000/health",
interval: 30000, // Проверка каждые 30 секунд
max_retries: 3
}
}]
};
Часто задаваемые вопросы (FAQ)
Как настроить PM2 для нескольких приложений?
В одном файле ecosystem.config.js можно описать несколько приложений:
module.exports = {
apps: [
{
name: "api-server",
script: "./api/server.js",
instances: 2,
env: { PORT: 3001 }
},
{
name: "worker-queue",
script: "./workers/queue.js",
instances: 1,
env: { REDIS_URL: "redis://localhost" }
},
{
name: "websocket-server",
script: "./ws/server.js",
instances: 1,
env: { PORT: 3002 }
}
]
};
Как настроить PM2 с Nginx?
Пример конфигурации Nginx для проксирования к PM2:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Как обновить приложение без простоя?
Используйте graceful reload:
# Для кластерного режима - поочередный перезапуск
pm2 reload ecosystem.config.js
# Или для конкретного приложения
pm2 reload my-app
# С автоматическим откатом при ошибке
pm2 reload my-app --safe
Заключение
Правильная настройка PM2 превращает твое Node.js приложение в надежную продакшн-систему. Ключевые моменты:
- Всегда используй
ecosystem.config.jsдля конфигурации - Настраивай кластеризацию для максимального использования ресурсов CPU
- Не забывай про логирование и ротацию логов
- Настрой автозагрузку через
pm2 startup - Используй разные окружения для development/staging/production
- Регулярно обновляй PM2 до последней версии
Следуя этим рекомендациям, ты сможешь настроить PM2 для работы в любой среде - от небольшого VPS до масштабируемого облачного кластера.