← Назад к вопросам
Что такое ThreadPool?
2.3 Middle🔥 181 комментариев
#Node.js и JavaScript#Архитектура и паттерны
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
ThreadPool — пул потоков для параллельной обработки
ThreadPool (пул потоков) — это механизм управления потоками, который позволяет эффективно распределять работу между потоками.
Концепция ThreadPool
Без ThreadPool:
Каждая задача → новый поток → много overhead
С ThreadPool:
Все задачи → одна очередь → несколько переиспользуемых потоков
ThreadPool в Node.js (Worker Threads)
Node.js работает в одном потоке, но для CPU-intensive задач можно использовать Worker Threads.
Проблема:
const crypto = require('crypto');
function heavyComputation(data) {
// Это блокирует event loop!
return crypto.pbkdf2Sync(data, 'salt', 100000, 64, 'sha512');
}
app.post('/compute', (req, res) => {
const result = heavyComputation(req.body.data);
res.json({ result }); // Ответ задерживается!
});
Тяжёлое вычисление блокирует event loop, все остальные запросы ждут.
Решение: Worker Pool
const { Worker } = require('worker_threads');
const path = require('path');
class WorkerPool {
constructor(workerScript, poolSize = 4) {
this.workers = [];
this.taskQueue = [];
this.activeWorkers = new Set();
for (let i = 0; i < poolSize; i++) {
this.workers.push(this.createWorker(workerScript));
}
}
createWorker(workerScript) {
const worker = new Worker(workerScript);
worker.on('message', (result) => {
this.activeWorkers.delete(worker);
if (this.taskQueue.length > 0) {
const { data, resolve } = this.taskQueue.shift();
this.executeTask(worker, data, resolve);
}
});
return worker;
}
executeTask(worker, data, resolve) {
this.activeWorkers.add(worker);
worker.once('message', (result) => {
resolve(result);
});
worker.postMessage(data);
}
async run(data) {
return new Promise((resolve) => {
const freeWorker = this.workers.find(
w => !this.activeWorkers.has(w)
);
if (freeWorker) {
this.executeTask(freeWorker, data, resolve);
} else {
this.taskQueue.push({ data, resolve });
}
});
}
terminate() {
this.workers.forEach(w => w.terminate());
}
}
const pool = new WorkerPool(path.join(__dirname, 'worker.js'), 4);
app.post('/compute', async (req, res) => {
const result = await pool.run(req.body.data);
res.json(result);
});
ThreadPool в других контекстах
Connection Pool (БД):
const pg = require('pg');
const pool = new pg.Pool({
max: 20, // Максимум подключений
min: 5, // Минимум готовых
connectionTimeoutMillis: 2000,
idleTimeoutMillis: 30000
});
app.get('/users', async (req, res) => {
// Используем существующее подключение
const result = await pool.query('SELECT * FROM users');
res.json(result.rows);
});
Job Queue (фоновые задачи):
const Bull = require('bull');
const jobQueue = new Bull('email-queue');
// 4 рабочих обрабатывают параллельно
jobQueue.process(4, async (job) => {
await sendEmail(job.data.email, job.data.subject);
return { success: true };
});
app.post('/send-email', async (req, res) => {
const job = await jobQueue.add(
{ email: req.body.email, subject: 'Hello' },
{ attempts: 3 }
);
res.json({ jobId: job.id });
});
Сравнение подходов
| Подход | Плюсы | Минусы | Когда |
|---|---|---|---|
| Single Thread | Просто | Медленно | I/O операции |
| Worker Pool | Параллелизм | Overhead памяти | CPU-intensive |
| Connection Pool | Эффективно | Сложнее | БД операции |
| Job Queue | Асинхронно | Отдельный сервис | Фоновые задачи |
Best Practices
// 1. Размер пула = CPU ядра для CPU-intensive
const os = require('os');
const poolSize = os.cpus().length;
// 2. Для I/O пул может быть больше
const ioPoolSize = 20;
// 3. Graceful shutdown
process.on('SIGTERM', async () => {
pool.terminate();
process.exit(0);
});
Key takeaway
- ThreadPool = управление потоками через очередь
- В Node.js для CPU-intensive используй Worker Threads
- Для I/O используй Connection Pools или Job Queues
- Размер пула влияет на производительность
- Обрабатывай graceful shutdown