Очереди задач для TypeScript: полное руководство по Bull и Bee-Queue
При разработке современных веб-приложений на TypeScript часто возникает необходимость выполнять длительные или ресурсоёмкие операции асинхронно, не блокируя основной поток. Например: отправка email-уведомлений, генерация PDF-отчётов, обработка изображений или синхронизация с внешними API. Для решения этих задач используются очереди задач (job queues). В этой статье мы подробно рассмотрим две самые популярные библиотеки для TypeScript — Bull и Bee-Queue, а также разберём, как интегрировать их в ваш проект.
Зачем нужны очереди задач?
Очередь задач позволяет:
- Разделить ответственность — основной сервис отвечает только за постановку задачи, а обработчик — за её выполнение.
- Управлять нагрузкой — можно ограничить количество параллельных задач (concurrency).
- Гарантировать доставку — задачи не теряются даже при падении процесса (благодаря Redis).
- Планировать выполнение — отложить задачу на определённое время или повторять её по расписанию.
- Обрабатывать ошибки — автоматические повторные попытки (retry) с экспоненциальной задержкой.
Bull — самая популярная очередь для Node.js и TypeScript
Bull — это мощная библиотека на основе Redis, поддерживающая полный набор функций: приоритеты, повторные попытки, задержки, паузы, события и мониторинг. Bull имеет отличную типизацию для TypeScript.
Установка и настройка
npm install bull @types/bull
Простой пример очереди для отправки email:
import Queue from 'bull';
interface EmailJob {
to: string;
subject: string;
body: string;
}
// Создаём очередь с именем 'email'
const emailQueue = new Queue<EmailJob>('email', {
redis: { host: 'localhost', port: 6379 },
defaultJobOptions: {
attempts: 3, // до 3 попыток
backoff: { type: 'exponential', delay: 2000 },
removeOnComplete: true,
}
});
// Обработчик — выполняется в фоне
emailQueue.process(async (job) => {
console.log(`Отправка email на ${job.data.to}`);
// Имитация отправки
await new Promise(resolve => setTimeout(resolve, 1000));
console.log(`Email отправлен: ${job.data.subject}`);
});
// Добавляем задачу
async function addEmail() {
await emailQueue.add({
to: 'user@example.com',
subject: 'Привет из очереди!',
body: 'Это тестовое письмо.',
});
}
addEmail();
Продвинутые возможности Bull
- Повторяющиеся задачи (cron):
queue.add(data, { repeat: { cron: '0 8 * * *' } }) - Приоритеты:
queue.add(data, { priority: 1 })— чем меньше число, тем выше приоритет. - Задержка выполнения:
queue.add(data, { delay: 60000 })— отложить на 1 минуту. - События: можно подписаться на
completed,failed,progressи другие. - Пауза/возобновление:
queue.pause()/queue.resume().
// Обработка событий
emailQueue.on('completed', (job, result) => {
console.log(`Задача ${job.id} завершена`);
});
emailQueue.on('failed', (job, err) => {
console.error(`Задача ${job.id} провалилась: ${err.message}`);
});
Bee-Queue — лёгкая альтернатива
Bee-Queue — это минималистичная очередь на Redis, которая проще и быстрее Bull в плане потребления памяти. Подходит для небольших проектов или случаев, когда не нужны сложные настройки.
Установка и пример
npm install bee-queue
import Bee from 'bee-queue';
interface ImageJob {
imageId: string;
format: 'png' | 'jpg';
}
const imageQueue = new Bee<ImageJob>('image-processing', {
redis: { host: 'localhost', port: 6379 },
isWorker: true,
removeOnSuccess: true,
});
// Обработчик
imageQueue.process(async (job) => {
console.log(`Обработка изображения ${job.data.imageId} в формат ${job.data.format}`);
// Имитация обработки
await new Promise(resolve => setTimeout(resolve, 2000));