Worker threads и cluster

↑ 6.1 Node.js изнутри · ← Предыдущая

По желанию~3 мин чтенияУровень: junior

Зачем это на собесе

Как использовать несколько ядер в Node.js и как выполнять тяжёлые вычисления.

Объяснение

МеханизмЧто этоДля чего
clusterнесколько процессов Node.js на одном портумасштабирование HTTP-сервера по ядрам
worker_threadsпотоки со своим event loop и памятью V8CPU-bound вычисления, не блокирующие главный поток
child_processзапуск внешних процессоввызов утилит
Контейнеры/процесс-менеджеры (PM2, Kubernetes)несколько репликпредпочтительный способ масштабирования
// main.js
import { Worker } from "node:worker_threads";
const run = (n) => new Promise((resolve, reject) => {
  const w = new Worker(new URL("./fib.js", import.meta.url), { workerData: n });
  w.once("message", resolve); w.once("error", reject);
});
console.log(await run(42));
 
// fib.js
import { parentPort, workerData } from "node:worker_threads";
const fib = (n) => (n < 2 ? n : fib(n - 1) + fib(n - 2));
parentPort.postMessage(fib(workerData));

Данные между потоками копируются (structured clone), либо передаются без копирования через transfer и SharedArrayBuffer + Atomics.

Нюансы и подводные камни

  • Создание воркера дорого: используйте пул (Piscina).
  • Worker threads не ускоряют I/O-bound задачи.
  • Общее состояние приложения в cluster не разделяется: сессии и кэш храните во внешнем хранилище.
  • Состояние гонки возможно только при SharedArrayBuffer.
  • В контейнерах обычно проще запускать по одному процессу на контейнер и масштабировать репликами.

Практика

  1. Вынесите тяжёлое вычисление в worker и сравните задержку API.
  2. Настройте пул воркеров через Piscina.
  3. Запустите приложение в cluster и проверьте распределение запросов.

Вопросы с ответами

Связанные темы