Как работает кластеризация Node.js приложений с PM2?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Кластеризация Node.js приложений с PM2
PM2 - это менеджер процессов для Node.js, который позволяет запускать несколько экземпляров приложения, используя все доступные ядра CPU. Поскольку Node.js работает в однопоточном режиме (один event loop на процесс), кластеризация - ключевой механизм масштабирования на многоядерных серверах.
Принцип работы
PM2 использует встроенный модуль cluster из Node.js. Создается master-процесс, который форкает несколько worker-процессов. Каждый worker - полноценный экземпляр приложения со своим event loop и памятью:
// ecosystem.config.js
module.exports = {
apps: [{
name: "api",
script: "./dist/server.js",
instances: "max", // по числу ядер CPU
exec_mode: "cluster", // режим кластера
max_memory_restart: "500M",
env: {
NODE_ENV: "production",
PORT: 3000
}
}]
};
pm2 start ecosystem.config.js
pm2 status # покажет все worker-процессы
Балансировка нагрузки
PM2 использует round-robin стратегию балансировки (по умолчанию на Linux). Master-процесс принимает входящие соединения на порт и распределяет их между worker-ами поочередно:
Client Request -> Master (port 3000)
|-- Worker 1 (обрабатывает запрос)
|-- Worker 2
|-- Worker 3
|-- Worker 4
На Windows используется стратегия ОС, где сокет шарится между процессами.
Zero-Downtime Reload
Одно из главных преимуществ PM2 кластера - перезапуск без простоя:
pm2 reload api # graceful reload
PM2 перезапускает worker-ы по одному: останавливает первый, ждет завершения запросов, поднимает новый, переходит к следующему. В любой момент времени часть worker-ов обслуживает запросы.
Проблемы и решения
1. Shared state: Каждый worker имеет свою память. Сессии, кеш и состояние нельзя хранить в памяти процесса:
// Плохо - каждый worker имеет свой кеш
const cache = new Map();
// Хорошо - внешнее хранилище
import Redis from "ioredis";
const redis = new Redis();
2. Sticky sessions: Для WebSocket/Socket.io нужны sticky sessions, чтобы клиент всегда попадал на тот же worker:
module.exports = {
apps: [{
script: "./server.js",
instances: "max",
exec_mode: "cluster",
wait_ready: true,
listen_timeout: 10000
}]
};
3. Порт: Все worker-ы слушают один и тот же порт. Не нужно настраивать разные порты.
4. Логирование: PM2 автоматически разделяет логи по worker-ам и поддерживает merge-режим.
Мониторинг
pm2 monit # real-time мониторинг CPU/RAM
pm2 logs # просмотр логов всех worker-ов
pm2 list # статус всех процессов
pm2 describe api # детальная информация
PM2 также предоставляет pm2.io - облачный мониторинг с алертами, метриками и удаленным управлением.