> Как писать приложение для корректной работы в кластерном режиме с несколькими воркерами (JavaScript)
Уровень: senior · Роль: backend · Язык: JavaScript · Категория: Технические вопросы
Компании: QueenInteractiveGamesLtd
Стек: Node.js, JavaScript
> Пример ответа
Для корректной работы Node.js приложения в кластерном режиме с несколькими воркерами необходимо учитывать несколько ключевых аспектов. Во-первых, используйте встроенный модуль cluster, который позволяет создавать дочерние процессы (воркеры), разделяющие один и тот же порт. Главный процесс (master) управляет воркерами, а каждый воркер обрабатывает запросы независимо.
Пример базовой реализации:
JAVASCRIPTconst cluster = require('cluster');const http = require('http');const numCPUs = require('os').cpus().length;if (cluster.isMaster) {console.log(`Master ${process.pid} запущен`);// Создаем воркеры по числу ядер CPUfor (let i = 0; i < numCPUs; i++) {cluster.fork();}// Перезапуск упавших воркеровcluster.on('exit', (worker, code, signal) => {console.log(`Воркер ${worker.process.pid} умер`);cluster.fork();});} else {// Воркеры: создаем HTTP серверhttp.createServer((req, res) => {res.writeHead(200);res.end('Hello from worker ' + process.pid);}).listen(8000);console.log(`Воркер ${process.pid} запущен`);}
Ключевые моменты для корректной работы:
-
Общее состояние: Избегайте хранения состояния в памяти воркера (например, сессии, кэш). Используйте внешние хранилища (Redis, база данных) для синхронизации между воркерами.
-
Грейсфул шатдаун: Обрабатывайте сигналы завершения (SIGTERM, SIGINT) для корректного закрытия соединений и освобождения ресурсов:
JAVASCRIPTprocess.on('SIGTERM', () => {server.close(() => process.exit(0));}); -
Балансировка нагрузки: Node.js автоматически распределяет входящие соединения между воркерами через round-robin (на Linux) или через сокеты (на Windows). Для более тонкой настройки используйте сторонние балансировщики (NGINX).
-
Логирование и мониторинг: Добавьте идентификатор воркера в логи (через
process.pidилиcluster.worker.id), чтобы отслеживать, какой воркер обрабатывает запрос. -
Избегайте блокирующих операций: Воркеры должны быть неблокирующими. Если есть тяжелые вычисления, выносите их в отдельные процессы или используйте worker_threads.
-
Обработка ошибок: Воркеры могут падать, поэтому мастер должен перезапускать их (как в примере выше). Также используйте
process.on('uncaughtException')для логирования, но не пытайтесь восстановить работу воркера - лучше дать ему умереть и перезапустить.
Этот подход обеспечивает отказоустойчивость, масштабирование и корректную работу приложения в многопроцессной среде.
> Похожие задачи по JavaScript
Интересовались ли вы системным дизайном
Как выглядела структура проекта и где была сосредоточена логика
Какие тактические шаблоны DDD вы знаете и применяли
Что такое нормализация и денормализация баз данных
> Похожие задачи по backend
Как работать со сложными запросами в PostgreSQL
Что такое Redis Cluster
В чем преимущество PostgreSQL перед MongoDB
Столкнулись ли вы с типами данных массивы и JSON в PostgreSQL
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью