Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що таке модуль cluster?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)`cluster` - вбудований модуль Node.js, що запускає кілька копій одного застосунку (воркерів), розподіляючи вхідні запити між ними через один спільний порт за принципом Round Robin. **Ключове:** кожен воркер - окремий процес зі своїм event loop, тож падіння одного не впливає на решту.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке `cluster` > `cluster` - це вбудований модуль Node.js, > який дозволяє запускати **кілька копій одного й того самого застосунку (воркерів)**, > розподіляючи вхідні запити між ними через **один спільний порт**. Простіше кажучи: > `cluster` робить Node.js багатопроцесним - створює "чергу" воркерів, > де кожен воркер - це окремий процес Node.js із власним event loop. ## Навіщо потрібен `cluster` За замовчуванням Node.js працює **в одному потоці** й використовує **лише одне ядро процесора**. Якщо в тебе сервер із 8 ядрами, то без кластеризації 7 з них будуть простоювати. **Рішення:** - `cluster` дозволяє запустити **кілька воркерів** (за кількістю ядер CPU), - і **розподіляти навантаження** між ними автоматично. ## 1. Проста схема роботи ```javascript ┌─────────────────────┐ │ Master Process │ ← слухає порт (наприклад, 3000) │ (головний) │ └────────┬────────────┘ │ ┌───────┴────────┬────────┬────────┐ │ │ │ │ ▼ ▼ ▼ ▼ Worker 1 Worker 2 Worker 3 Worker 4 (порт 3000) (порт 3000) ... ``` - Усі воркери слухають **один і той самий порт**. - Node.js (через master) **балансує запити** між ними (Round Robin). - Кожен воркер - **окремий процес**, тому падіння одного не впливає на решту. ## 2. Приклад використання `cluster` **server.js** ```javascript 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 | Повідомлення між процесами | Приклад: ```javascript cluster.on('online', (worker) => console.log(`Воркер ${worker.process.pid} готовий`)); ``` ## 5. Обмін даними між master і worker Ти можеш передавати дані між процесами (як у `child_process`): **master** ```javascript worker.send({ msg: 'Привіт від майстра!' }); ``` **worker** ```javascript 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-сервер із кластеризацією:** ```javascript 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-серверів.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.