Що таке модуль cluster?
Що таке cluster
cluster- це вбудований модуль Node.js, який дозволяє запускати кілька копій одного й того самого застосунку (воркерів), розподіляючи вхідні запити між ними через один спільний порт.
Простіше кажучи:
clusterробить Node.js багатопроцесним - створює "чергу" воркерів, де кожен воркер - це окремий процес Node.js із власним event loop.
Навіщо потрібен cluster
За замовчуванням Node.js працює в одному потоці й використовує лише одне ядро процесора. Якщо в тебе сервер із 8 ядрами, то без кластеризації 7 з них будуть простоювати.
Рішення:
clusterдозволяє запустити кілька воркерів (за кількістю ядер CPU),- і розподіляти навантаження між ними автоматично.
1. Проста схема роботи
┌─────────────────────┐
│ Master Process │ ← слухає порт (наприклад, 3000)
│ (головний) │
└────────┬────────────┘
│
┌───────┴────────┬────────┬────────┐
│ │ │ │
▼ ▼ ▼ ▼
Worker 1 Worker 2 Worker 3 Worker 4
(порт 3000) (порт 3000) ...- Усі воркери слухають один і той самий порт.
- Node.js (через master) балансує запити між ними (Round Robin).
- Кожен воркер - окремий процес, тому падіння одного не впливає на решту.
2. Приклад використання cluster
server.js
const cluster = require('cluster');
const http = require('http');
const os = require('os');
if (cluster.isPrimary) {
// Головний процес
const numCPUs = os.cpus().length;
console.log(`Головний процес ${process.pid}. Запускаємо ${numCPUs} воркерів...`);
// Створюємо воркерів за кількістю ядер
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
// Коли воркер вмирає - створюємо нового
cluster.on('exit', (worker) => {
console.log(`Воркер ${worker.process.pid} завершився. Перезапуск...`);
cluster.fork();
});
} else {
// Воркери (обробляють запити)
http.createServer((req, res) => {
res.end(`Відповідь від воркера ${process.pid}\n`);
}).listen(3000);
console.log(`Воркер ${process.pid} запущено`);
}Що відбувається:
- Головний процес (
isPrimary) створює воркерів за допомогоюcluster.fork(). - Кожен воркер - це новий процес Node.js.
- Усі воркери слухають один і той самий порт (
3000). - Запити автоматично розподіляються між ними.
3. Як відбувається балансування
Node.js сам реалізує Round-Robin Load Balancing:
- Головний процес приймає з'єднання на основному порту.
- Потім рівномірно розподіляє їх між воркерами.
Це означає:
тобі не потрібно налаштовувати Nginx чи зовнішній балансувальник, усе робиться "з коробки" на рівні Node.js.
4. Події модуля cluster
| Подія | Де спрацьовує | Що робить |
|---|---|---|
fork | master | Новий воркер створено |
online | master | Воркер запущено |
listening | master | Воркер слухає порт |
exit | master | Воркер завершив роботу |
message | master ↔ worker | Повідомлення між процесами |
Приклад:
cluster.on('online', (worker) => console.log(`Воркер ${worker.process.pid} готовий`));5. Обмін даними між master і worker
Ти можеш передавати дані між процесами (як у child_process):
master
worker.send({ msg: 'Привіт від майстра!' });worker
process.on('message', (data) => {
console.log('Отримано:', data);
process.send({ reply: 'Привіт назад!' });
});6. Відмінність cluster від worker_threads
| Критерій | cluster | worker_threads |
|---|---|---|
| Одиниця виконання | Процес | Потік |
| Пам'ять | Окрема | Спільна (через SharedArrayBuffer) |
| Event Loop | Свій у кожного | Свій у кожного |
| Підходить для | Вебсерверів, API, масштабування | Обчислювальних задач |
| Обмін даними | Через IPC (JSON) | Через SharedArrayBuffer, Atomics |
| Перезапуск воркерів | Автоматично | Ручний контроль |
| Ізоляція помилок | Повна | Часткова |
Іншими словами:
cluster- це мультипроцесна архітектура для навантаження по CPU.worker_threads- багатопотокова модель для важких обчислень усередині одного процесу.
7. Приклад реального використання
Express-сервер із кластеризацією:
const cluster = require('cluster');
const os = require('os');
const express = require('express');
if (cluster.isPrimary) {
const numCPUs = os.cpus().length;
for (let i = 0; i < numCPUs; i++) cluster.fork();
} else {
const app = express();
app.get('/', (req, res) => res.send(`Handled by worker ${process.pid}`));
app.listen(3000, () => console.log(`Worker ${process.pid} started`));
}Тепер кожен воркер обробляє частину запитів → застосунок масштабується автоматично.
8. Переваги й недоліки
| Переваги | Недоліки |
|---|---|
| Використовує всі CPU ядра | Кожен воркер - окремий процес (пам'ять ×N) |
| Проста настройка | Складніше налагоджувати |
| Висока стійкість | Немає спільної пам'яті (тільки через IPC) |
| Автоматичне відновлення | Балансування на рівні TCP (можливе обмеження при WebSocket) |
Підсумок
| Критерій | Опис |
|---|---|
| Призначення | Масштабування Node.js-застосунку по всіх ядрах CPU |
| Реалізація | Кілька процесів Node.js (воркерів) |
| Керується | Головним процесом (master) |
| Розподіл навантаження | Round Robin |
| Обмін даними | IPC (worker.send, process.on('message')) |
| Ідеально підходить для | Серверів, API, мікросервісів |
Висновок:
Модуль
clusterдозволяє Node.js використовувати всі ядра процесора, створюючи кілька незалежних процесів (воркерів), які спільно обробляють запити на одному порту.Це - вбудований "з коробки" механізм масштабування й відмовостійкості для Node.js-серверів.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.