Загрузка…
Загрузка…
Node.js · middle · сложность 5
Как опытный технический интервьюер и преподаватель, я часто считаю, что понимание того, как Node.js использует многоядерные системы, несмотря на то, что он однопоточный, является важнейшей концепцией. Давайте разберем это понятным и понятным для новичков способом.
cluster
Модуль позволяет приложениям Node.js использовать преимущества многоядерных систем. Каковы проблемы и соображения при использовании
cluster
для масштабирования, особенно в отношении общего состояния и межпроцессного взаимодействия (IPC)?
По своей сути один процесс Node.js выполняется в одном потоке. Представьте себе высокоэффективного повара (процесс Node.js), работающего в одиночку на кухне. Этот повар может одновременно выполнять только одну задачу (например, нарезать овощи, затем помешать кастрюлю, затем приправить блюдо). Даже ожидая чего-то (например, закипания воды), повар достаточно умен, чтобы тем временем выполнять другие задачи (проверять другое блюдо, убирать). Это «умное ожидание» аналогично циклу событий Node.js и неблокирующему вводу-выводу, что делает его очень эффективным для задач, связанных с вводом-выводом (например, веб-серверы, работающие с множеством одновременных подключений).
Преимущества однопоточного режима:
Ограничения однопоточного режима:
cluster
Модуль: Использование многоядерных систем
Именно здесь
cluster
модуль вступает в игру. Он предоставляет способ преодолеть однопоточное ограничение, позволяя одному приложению Node.js разветвляться (создавать) себя в несколько рабочих процессов.
Подумайте об этом так: если один повар может использовать только одну часть кухни, что, если мы наймем больше поваров? Теперь у нас может быть несколько поваров, каждый из которых работает на своем участке кухни, что позволяет нам готовить больше еды одновременно и использовать все пространство кухни (все ядра процессора).
**Как
cluster
Работы (модель Мастер-Работник):**
cluster
используется, этот первоначальный процесс становится главным. Роль мастера — не обрабатывать входящие запросы напрямую, а управлять рабочими процессами. Это похоже на начальника кухни, который нанимает и контролирует поваров. 2. Рабочие процессы. Затем главный процесс использует
cluster.fork()
метод для создания нескольких новых процессов Node.js. Каждый из этих новых процессов является работником. Каждый рабочий процесс запускает экземпляр кода вашего приложения и имеет собственное изолированное пространство памяти. Это ваши индивидуальные повара. 3. Общий порт и балансировка нагрузки. Все рабочие процессы настроены на использование одного и того же порта сервера (например, порта 3000). При поступлении нового входящего запроса операционная система (ОС) или внешний балансировщик нагрузки (если он настроен) распределяет этот запрос по доступным рабочим процессам. Это похоже на то, как клиенты приходят в ресторан, и хост (ОС/балансировщик нагрузки) направляет их к свободному шеф-повару.
**Визуализация
cluster
Модуль:**
+------------------+ +------------------+ +------------------+
| | | | | |
| Worker Process | | Worker Process | | Worker Process |
| (Node.js App) | | (Node.js App) | | (Node.js App) |
| Handles Req A | | Handles Req B | | Handles Req C |
| | | | | |
+------------------+ +------------------+ +------------------+
^ ^ ^
| | |
+-----------------------+-----------------------+
|
OS / Load Balancer
|
| Distributes incoming requests
|
+-------------+
| Master Process |
| (Node.js App) |
| Manages Workers|
| Forks |
+-------------+**Пример кода: базовый
cluster
Настраивать**
const кластер = требуется ('кластер');
const http = require('http');
const numCPUs = require('os').cpus().length; // Получаем количество ядер ЦП
if (cluster.isMaster) { // Или кластер.isPrimary в новых версиях Node.js
консоль.log(
`Master ${process.pid} is running`
);
// Вилочные рабочие.
ибо (пусть я = 0; я {
консоль.log(
`Worker ${worker.process.pid} died`
);
// При желании перефоркните нового работника, если он умирает, для поддержания параллелизма
// кластер.форк();
});
} еще {
// Воркеры могут использовать любое TCP-соединение
// В данном случае это HTTP-сервер
http.createServer((req, res) => {
res.writeHead(200);
рез.конец(
`Hello from worker ${process.pid}!\n`
);
// Имитация некоторой работы, связанной с процессором (не делайте этого в реальных приложениях без необходимости)
// пусть j = 0;
// for (пусть i = 0; i {
if (msg.cmd && msg.cmd === 'reportRequest') {
тотальные запросы++;
консоль.log(
`Master: Total requests handled: ${totalRequests}`
);
// При желании отправьте сообщение обратно работнику
worker.send({ cmd: 'updateStatus', статус:
`Processed ${totalRequests} requests`
});
}
});
}
Cluster.on('exit', (работник, код, сигнал) => {
## Итог
Ключевой вывод из интервью: Node.js является однопоточным. Объясните, как модуль `cluster` позволяет приложениям Node.js использовать преимущества многоядерности.