← Назад к вопросам
Как реализовать многопоточность используя userland в Node.js?
2.8 Senior🔥 91 комментариев
#Node.js и JavaScript#Архитектура и паттерны#Кэширование и производительность
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Многопоточность в userland Node.js
Многопоточность в Node.js реализуется через несколько подходов на уровне приложения (userland), так как сам Node.js работает в single-threaded event loop.
Основные методы
1. Worker Threads (встроенное решение)
Это официальный способ для CPU-bound задач:
const { Worker } = require('worker_threads');
const path = require('path');
// Создание рабочего потока
const worker = new Worker(path.join(__dirname, 'worker.js'));
// Отправка данных
worker.postMessage({ data: 'hello' });
// Получение результата
worker.on('message', (result) => {
console.log('Результат:', result);
});
worker.on('error', reject);
worker.on('exit', (code) => {
if (code !== 0) reject(new Error(`Worker exited with code ${code}`));
});
В worker.js:
const { parentPort } = require('worker_threads');
parentPort.on('message', (msg) => {
const result = msg.data.toUpperCase();
parentPort.postMessage(result);
});
2. Cluster Module (для масштабирования)
Используется для распределения нагрузки между процессами:
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} умер`);
cluster.fork();
});
} else {
// Рабочий процесс
http.createServer((req, res) => {
res.writeHead(200);
res.end('Hello World\n');
}).listen(8000);
}
3. Thread Pool (пула потоков)
Управление пулом рабочих потоков для многозадачности:
const { Worker } = require('worker_threads');
class ThreadPool {
constructor(size) {
this.workers = [];
this.queue = [];
for (let i = 0; i < size; i++) {
const worker = new Worker('./worker.js');
worker.busy = false;
this.workers.push(worker);
}
}
execute(task) {
return new Promise((resolve, reject) => {
const availableWorker = this.workers.find(w => !w.busy);
if (availableWorker) {
availableWorker.busy = true;
availableWorker.once('message', (result) => {
availableWorker.busy = false;
resolve(result);
this.processQueue();
});
availableWorker.postMessage(task);
} else {
this.queue.push({ task, resolve, reject });
}
});
}
processQueue() {
if (this.queue.length === 0) return;
const { task, resolve, reject } = this.queue.shift();
this.execute(task).then(resolve).catch(reject);
}
}
Когда использовать
- Worker Threads: CPU-intensive операции (обработка изображений, крипто, вычисления)
- Cluster: Масштабирование HTTP сервера на много ядер
- Async/Await + Event Loop: I/O операции (БД, API запросы) — не требуют отдельных потоков
Best Practices
- Переиспользуй workers вместо создания новых
- Ограничивай размер очереди
- Обрабатывай ошибки и graceful shutdown
- Для I/O операций используй асинхронный код, не workers