Ответ
Worker Threads — это механизм в Node.js для выполнения JavaScript-кода в параллельных потоках. Они предназначены для выгрузки CPU-интенсивных (блокирующих) задач из основного потока Event Loop, чтобы не блокировать обработку входящих запросов и асинхронных операций I/O.
Ключевые отличия от кластеризации (cluster):
- Кластер (
cluster): Создаёт несколько независимых процессов (инстансов Node.js), каждый со своей памятью. Подходит для масштабирования сетевых приложений, так как процессы не разделяют память и общаются через IPC. - Worker Threads: Создаёт несколько потоков в рамках одного процесса. Потоки могут (опционально) разделять память через
SharedArrayBuffer, что делает их более подходящими для параллельных вычислений над общими данными.
Основные концепции и API:
Worker: Класс для создания нового потока.parentPort: Канал для обмена сообщениями между главным потоком и воркером.workerData: Позволяет передать начальные данные в воркер при его создании.MessageChannel: Создаёт канал для прямого общения между воркерами.
Пример: вычисление числа Фибоначчи в отдельном потоке
main.js (главный поток):
const { Worker } = require('worker_threads');
const path = require('path');
function runFibonacciService(n) {
return new Promise((resolve, reject) => {
// Создаём воркер и передаём ему данные
const worker = new Worker(path.join(__dirname, 'fibonacci-worker.js'), {
workerData: n
});
worker.on('message', resolve); // Получаем результат
worker.on('error', reject); // Обрабатываем ошибки в воркере
worker.on('exit', (code) => {
if (code !== 0) {
reject(new Error(`Worker stopped with exit code ${code}`));
}
});
});
}
// Использование
(async () => {
console.log('Main thread: starting heavy calculation...');
const result = await runFibonacciService(40); // Блокирующая операция
console.log(`Main thread: result = ${result}`);
// Event Loop в основном потоке не был заблокирован!
})();
fibonacci-worker.js (код воркера):
const { parentPort, workerData } = require('worker_threads');
// Рекурсивная функция, тяжелая для CPU
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
// Выполняем вычисление и отправляем результат обратно в главный поток
const result = fibonacci(workerData);
parentPort.postMessage(result);
Когда использовать Worker Threads:
- Обработка изображений/видео.
- Синтаксический анализ или сжатие больших объёмов данных.
- Сложные математические вычисления, машинное обучение.
- Любые синхронные задачи, которые занимают более 10-30 мс и блокируют Event Loop.
Важно: Worker Threads не предназначены для увеличения производительности I/O-операций (работа с файлами, сетью). Для этого эффективнее использовать асинхронные API самого Node.js.