Как Node.js использует несколько ядер
Вопрос
Node однопоточный. Как тогда загрузить сервер с 16 ядрами и не блокироваться на тяжёлых вычислениях?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
JS в одном потоке, но libuv уже использует пул для fs/crypto/zlib
Несколько процессов: cluster, PM2 или реплики в контейнерах за балансировщиком
Память процессов не общая: состояние во внешнем хранилище
worker_threads для CPU-работы, пул воркеров
Воркеры не ускоряют ввод-вывод
Выбор зависит от инфраструктуры: в Kubernetes один процесс на контейнер
Что могут спросить следом
- Чем процесс отличается от потока в контексте Node?
- Как передать большие данные в воркер без копирования?
- Что будет с WebSocket при нескольких процессах?
Разбор
JavaScript в процессе Node выполняется в одном потоке, хотя сам Node многопоточный внутри: libuv держит пул для файлов, DNS и криптографии.
Чтобы задействовать все ядра под HTTP, запускаю несколько процессов. На голой машине это модуль cluster или PM2: процессы слушают один порт, а главный раздаёт соединения. В Kubernetes проще: один процесс на контейнер и столько реплик, сколько нужно. В обоих случаях память не общая, поэтому сессии и кеш выношу в Redis.
Другая задача это тяжёлые вычисления: ресайз картинок, парсинг, сжатие. Они блокируют цикл своего процесса, и cluster тут не спасает. Такую работу отдаю пулу worker_threads, например через piscina. Данные передаю сообщениями, большие буферы через transfer list.
А запросы к базе и HTTP-вызовы в воркеры не выношу: это ввод-вывод, он и так не блокирует.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Термины по теме
Ещё по теме «Кластер, воркеры, масштабирование»
- Консистентное хеширование с виртуальными узлами
- Балансировка least connections
- Плавный взвешенный round-robin как в nginx
- Код-ревью: сервис перед масштабированием в 4 инстанса
- Модуль cluster
- cluster внутри Kubernetes
- Память у воркеров cluster
- cluster или worker_threads