Ответ
Cluster — это встроенный модуль Node.js, который позволяет создавать несколько дочерних процессов (воркеров) для параллельного выполнения кода на многоядерных процессорах. Поскольку Node.js работает в одном потоке, кластеризация — это основной способ горизонтального масштабирования приложения на уровне ОС.
Как это работает:
- Главный процесс (master) создаёт несколько воркеров с помощью
cluster.fork(). - Все воркеры выполняют один и тот же исходный код сервера.
- Входящие соединения распределяются между воркерами (по умолчанию — алгоритм round-robin).
- Воркеры используют общий серверный порт через механизм IPC (Inter-Process Communication).
Пример базовой реализации:
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isPrimary) {
console.log(`Primary process ${process.pid} is running`);
// Создаём воркеров по количеству ядер CPU
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`Worker ${worker.process.pid} died. Restarting...`);
cluster.fork(); // Автоматический перезапуск упавшего воркера
});
} else {
// Код, выполняемый воркерами
http.createServer((req, res) => {
res.writeHead(200);
res.end(`Response from worker ${process.pid}`);
}).listen(3000);
console.log(`Worker ${process.pid} started`);
}
Практическое применение: Кластеризация критически важна для веб-серверов (например, на Express.js или Fastify), чтобы полностью использовать ресурсы сервера и повысить отказоустойчивость. В продакшене часто используется в связке с менеджером процессов PM2, который предоставляет более удобный интерфейс для кластеризации.
Ответ 18+ 🔞
Э, слушай, а давай про эту вашу кластеризацию в Node.js поговорим. Вещь, в общем-то, архиполезная, а многие её как мантру повторяют, не особо вникая, что там под капотом. Ну, типа, «надо форкаться, ядра использовать». А почему? А потому что Node.js, он, сука, однопоточный, как этот твой знакомый, который в доту режется и на звонки не отвечает. Всё в одном потоке крутится. И если у тебя сервак на 16 ядер, а приложение в одном ядре сидит — это же пиздец, товарищ. Остальные 15 ядер просто курят в сторонке, пока одно ядро ебётся с нагрузкой. Волнение ебать просто от такой несправедливости.
Так вот, модуль cluster — это как раз способ сказать системе: «Эй, ядра, ёпта, не проёбывайтесь!». Главный процесс, он же мастер, запускается. Его задача — наделать кучу детей-воркеров. Каждый воркер — это отдельный процесс Node.js, который тупо выполняет ТОТ ЖЕ САМЫЙ код твоего сервера. И все они, ебушки-воробушки, начинают слушать один и тот же порт. Как так выходит? А это магия IPC (Inter-Process Communication), проще говоря, они между собой договариваются, кто из них какой запрос обработает.
Самый простой пример, чтоб въехать, выглядит как-то так:
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isPrimary) {
console.log(`Primary process ${process.pid} is running`);
// Создаём воркеров по количеству ядер CPU
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`Worker ${worker.process.pid} died. Restarting...`);
cluster.fork(); // Автоматический перезапуск упавшего воркера
});
} else {
// Код, выполняемый воркерами
http.createServer((req, res) => {
res.writeHead(200);
res.end(`Response from worker ${process.pid}`);
}).listen(3000);
console.log(`Worker ${process.pid} started`);
}
Смотри, что тут происходит. Мастер (cluster.isPrimary) — он плодовитый такой, хуй с горы. Берёт количество ядер на твоей машине и на каждое ядро создаёт по воркеру (cluster.fork()). А дальше он просто сидит и ждёт. Если какой-то воркер, не дай бог, накрылся медным тазом и умер, мастер это видит (cluster.on('exit')) и тут же запускает нового. Отказоустойчивость, мать её.
А воркеры — они уже тупо запускают сервер. Весь код после else — это их жизнь. Они все стартуют HTTP-сервер на порту 3000. И когда приходит запрос, операционка (или сам Node, смотря какая версия) по умолчанию раскидывает их по кругу (round-robin) между всеми воркерами. Один запрос — первому воркеру, второй — второму, и так по кругу. Распределение нагрузки, ёпта!
На практике это овердохуища важно для любого нормального веб-сервера на Express, Fastify или на чём ты там любишь. Без кластеризации ты используешь мощности своего сервера на 5-10%, а остальное — просто греет воздух. Это как купить Ferrari и кататься на ней только на первой передаче до магазина за хлебом. Удивление пиздец.
Правда, в реальной жизни народ редко пишет эту логику руками. Чаще используют PM2 — это такой менеджер процессов, который из коробки умеет и кластеризовать, и логи писать, и при падении перезапускать. Он под капотом делает всё то же самое, но тебе не нужно париться с этим кодом. Но понимать, как это работает — обязательно. А то будешь как полупидор, который PM2 запустил, а на вопрос «как это работает» — глаза в потолок. Не комильфо.