← Назад к вопросам

В чем разница между Worker Threads и Cluster в Node.js?

2.0 Middle🔥 91 комментариев
#Node.js и JavaScript

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Worker Threads и Cluster — это два разных способа создания параллелизма в Node.js. Они решают разные задачи и имеют разные архитектурные подходы.

Worker Threads

Worker Threads позволяют выполнять JavaScript код в отдельных потоках внутри одного процесса.

const {Worker} = require('worker_threads');

const worker = new Worker('./worker.js');

worker.on('message', (msg) => {
  console.log('From worker:', msg);
});

worker.postMessage('Hello Worker');

// worker.js
const {parentPort} = require('worker_threads');

parentPort.on('message', (msg) => {
  console.log('From parent:', msg);
  parentPort.postMessage('Response from worker');
});

Характеристики:

  • Общая память между потоками
  • Малый оверхед (меньше памяти)
  • Для CPU-интенсивных задач
  • Одно Node.js выполнение

Cluster

Cluster создает несколько отдельных Node.js процессов (воркеров).

const cluster = require('cluster');
const os = require('os');
const http = require('http');

if (cluster.isMaster) {
  const numCPUs = os.cpus().length;
  
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  
  cluster.on('exit', (worker) => {
    console.log(`Worker ${worker.process.pid} died`);
    cluster.fork(); // Перезапуск
  });
} else {
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end(`Worker ${process.pid}`);
  }).listen(3000);
}

Характеристики:

  • Отдельные процессы (каждый со своей памятью)
  • Большой оверхед (больше памяти)
  • Для I/O-интенсивных задач
  • Встроенная поддержка load balancing
  • Auto-restart при сбое

Сравнение

ПараметрWorker ThreadsCluster
ТипПотоки в одном процессеОтдельные процессы
ПамятьОбщая, малый оверхедОтдельная, большой оверхед
Общее состояниеМожет быть (осторожно!)Нет (отдельная память)
КоммуникацияpostMessage (быстро)IPC (медленнее)
ИзоляцияСлабаяСильная
ИспользованиеCPU-задачиWeb-сервер (I/O)
RestartРучнойАвтоматический

Worker Threads для CPU-интенсивных задач

const {Worker} = require('worker_threads');

// Основной поток
const http = require('http');

http.createServer((req, res) => {
  if (req.url === '/calculate') {
    // Создать worker для тяжелых вычислений
    const worker = new Worker('./calculator.js');
    
    worker.on('message', (result) => {
      res.writeHead(200);
      res.end(`Result: ${result}`);
      worker.terminate();
    });
    
    worker.postMessage(1000000); // Отправить данные
  } else {
    res.writeHead(200);
    res.end('OK');
  }
}).listen(3000);

// calculator.js (Worker)
const {parentPort} = require('worker_threads');

parentPort.on('message', (num) => {
  let result = 0;
  for (let i = 0; i < num; i++) {
    result += Math.sqrt(i);
  }
  parentPort.postMessage(result);
});

Cluster для Web-сервера

const cluster = require('cluster');
const os = require('os');
const http = require('http');
const {Server} = require('net');

if (cluster.isMaster) {
  const numCPUs = os.cpus().length;
  console.log(`Master ${process.pid} running`);
  
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  
  cluster.on('exit', (worker, code) => {
    console.log(`Worker ${worker.process.pid} died`);
    if (!worker.exitedAfterDisconnect) {
      console.log('Worker crashed, creating new one');
      cluster.fork();
    }
  });
} else {
  http.createServer((req, res) => {
    // Каждый worker обрабатывает запросы
    res.writeHead(200);
    res.end(`Handled by ${process.pid}`);
  }).listen(3000);
  
  console.log(`Worker ${process.pid} started`);
}

Когда использовать Worker Threads

// Тяжелые вычисления, обработка данных
const {Worker} = require('worker_threads');

// Парсинг больших JSON
const parseWorker = new Worker('./json-parser.js');

// Криптография
const cryptoWorker = new Worker('./crypto.js');

// Image processing
const imageWorker = new Worker('./image-processor.js');

Когда использовать Cluster

// Web-server, который обрабатывает много I/O запросов
const cluster = require('cluster');

if (cluster.isMaster) {
  // Автоматическое распределение нагрузки
  for (let i = 0; i < 4; i++) {
    cluster.fork();
  }
}

// Каждый воркер обрабатывает I/O независимо
app.get('/', async (req, res) => {
  const data = await db.query('...');
  res.json(data);
});

Гибридный подход

const cluster = require('cluster');
const {Worker} = require('worker_threads');
const os = require('os');

if (cluster.isMaster) {
  const numCPUs = os.cpus().length;
  
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
} else {
  const http = require('http');
  
  http.createServer((req, res) => {
    if (req.url === '/heavy') {
      // Использовать Worker для тяжелой работы
      const worker = new Worker('./heavy-task.js');
      
      worker.on('message', (result) => {
        res.end(result);
      });
    } else {
      res.end('OK');
    }
  }).listen(3000);
}

Примеры использования

Worker Threads для асинхронной обработки

const pWorker = require('piscina'); // Пул воркеров
const pool = new pWorker({filename: './worker.js'});

app.post('/process', async (req, res) => {
  try {
    const result = await pool.run(req.body);
    res.json(result);
  } catch (e) {
    res.status(500).json({error: e.message});
  }
});

Cluster для автомасштабирования

const cluster = require('cluster');

let workerCount = os.cpus().length;
let activeWorkers = 0;

if (cluster.isMaster) {
  for (let i = 0; i < workerCount; i++) {
    cluster.fork();
  }
  
  // Мониторинг и динамическое масштабирование
  setInterval(() => {
    const workers = Object.values(cluster.workers);
    console.log(`Active workers: ${workers.length}`);
  }, 10000);
}

Производительность

Worker Threads:

  • Быстрая коммуникация
  • Малая задержка
  • Хороший для CPU-bound

Cluster:

  • Медленнее (IPC)
  • Изолированная память
  • Хороший для I/O-bound

Вывод

  • Worker Threads — для CPU-интенсивных задач в одном процессе
  • Cluster — для масштабирования веб-серверов на несколько процессов
  • Hybrid approach — использовать оба вместе для оптимальной производительности
В чем разница между Worker Threads и Cluster в Node.js? | PrepBro