Inquir Compute · очередь задач

Serverless-очередь задач: уберите флот воркеров с Redis

BullMQ нужны Redis, воркер-процесс и стратегия ретраев. SQS нужны IAM, Lambda-консьюмер и настройка dead-letter-очереди. Пайплайны Inquir дают семантику продюсер/консьюмер — поставить задачу, выполнить её в изолированном контейнере, повторить упавшие шаги — без развёртывания и эксплуатации инфраструктуры очередей.

Обновлено: 2026-06-28

Суть ответа

Serverless-очередь задач: уберите флот воркеров с Redis. Inquir — не высокопроизводительный брокер сообщений со строгим порядком, но эксплуатировать такой брокер вам и не нужно. Пайплайны плюс очередь durable-задач (ретраи на Postgres, экспоненциальный backoff и dead-letter-очередь) снимают операционную нагрузку очереди — политика ретраев на шаг, история прогонов по шагам и выполнение в изолированных контейнерах, — так что вы пишете логику задач, а не инфраструктуру очереди.

Когда подходит

  • Нужны постановка в очередь, ретраи и история прогонов без эксплуатации Redis, SQS или флота воркеров
  • Фоновые задачи должны делить секреты и наблюдаемость с вашим HTTP API

На что обратить внимание

  • Очередь в памяти API-процесса теряет задачи при рестарте и не масштабируется горизонтально без дублей доставки. Воркер-процесс — самый хрупкий компонент: он должен постоянно работать, дорабатывать при деплое и переживать падения без потери задач в работе.
  • Вызов SQS из каждого обработчика размазывает IAM-учётки, логику ретраев и управление ключами идемпотентности по всей кодовой базе. Каждый новый тип задачи воспроизводит тот же шаблонный код.

Во что обходится продакшен-очередь задач

  • Бэкенд очереди: Redis, SQS или RabbitMQ — развёрнутый, под мониторингом и на критическом пути каждой задачи
  • Флот воркеров: постоянные процессы, которые читают очередь, масштабируются под нагрузку и безопасно дорабатывают при деплое
  • Политика ретраев и backoff: экспоненциальная задержка, лимит попыток и ручной разбор задач, исчерпавших ретраи
  • Наблюдаемость: отдельный дашборд для глубины очереди, зависших задач и причин сбоев

Очереди задач решают реальные проблемы: отделяют продюсеров от консьюмеров, сглаживают всплески трафика, повторяют нестабильную работу. Но сама очередь становится инфраструктурой, которую вы эксплуатируете ещё до первой бизнес-задачи.

Почему самодельные очереди добавляют операционный долг

Очередь в памяти API-процесса теряет задачи при рестарте и не масштабируется горизонтально без дублей доставки. Воркер-процесс — самый хрупкий компонент: он должен постоянно работать, дорабатывать при деплое и переживать падения без потери задач в работе.

Вызов SQS из каждого обработчика размазывает IAM-учётки, логику ретраев и управление ключами идемпотентности по всей кодовой базе. Каждый новый тип задачи воспроизводит тот же шаблонный код.

Пайплайны как продюсер/консьюмер без эксплуатации очереди

Inquir — не высокопроизводительный брокер сообщений со строгим порядком, но эксплуатировать такой брокер вам и не нужно. Пайплайны плюс очередь durable-задач (ретраи на Postgres, экспоненциальный backoff и dead-letter-очередь) снимают операционную нагрузку очереди — политика ретраев на шаг, история прогонов по шагам и выполнение в изолированных контейнерах, — так что вы пишете логику задач, а не инфраструктуру очереди.

Продюсер вызывает global.durable.startNew(jobName, undefined, payload) из любой функции. Консьюмер — обработчик шага пайплайна, который запускает управляемый пул воркеров (10 параллельно на функцию, 50 глобально, глубина внутренней очереди 100). Ни строки подключения к Redis, ни systemd-юнита воркера, ни скрипта дорабатывания очереди при деплое.

Сравнение эксплуатации очередей

Что вы разворачиваете и эксплуатируете при каждом подходе — сравнение не возможностей, а эксплуатации.

Сравнение эксплуатации очередей
Зона ответственностиBullMQ + RedisAWS SQS + LambdaПайплайны Inquir
Инфраструктура очередиКластер Redis (разворачиваете вы)Очередь SQS (управляет AWS)Нет — встроена в пайплайн
Воркер-процессВоркеры BullMQ (запускаете вы)Lambda-консьюмер (настраиваете вы)Шаги пайплайна (запускает платформа)
Настройка ретраевНа задачу в коде воркераRedrive policy + DLQНа шаг в конфигурации пайплайна
История прогонов / наблюдаемостьКлючи Redis (короткий TTL)CloudWatch + разбор DLQЗаписи выполнения (хранятся 30 дней)
Модель секретовОтдельно от HTTP-маршрутовIAM + Secrets ManagerОбщие секреты воркспейса
Гарантия доставкиAt-least-once через RedisAt-least-once через SQSAt-least-once (без гарантии порядка)

Паттерны очереди задач на Inquir

Постановка из любого продюсера

HTTP 202, проверенный вебхук, cron-расписание или шаг другого пайплайна — один вызов постановки (global.durable.startNew) независимо от точки входа.

Ретраи на шаг с backoff

Настройте число попыток и задержку на каждый шаг пайплайна. Упавшие шаги повторяются без перезапуска уже завершённых — аналог опций ретраев задачи, но без отдельной очереди ретраев.

История прогона как запись выполнения

Каждая постановка создаёт запись прогона: входной payload, выходы шагов, длительность, число ретраев и причина сбоя. Всё видно в консоли без запросов к Redis и проверки глубины DLQ.

Fan-out без второй очереди

Один шаг задачи вызывает global.durable.startNew() N раз и порождает параллельные дочерние пайплайны. Ни отдельного продукта-очереди, ни настройки fan-out по топикам.

Как заменить BullMQ или SQS пайплайнами Inquir

1

Написать обработчик консьюмера

Экспортируйте функцию, которая читает event.payload и возвращает структурированный выход, — сторона консьюмера. Сделайте её идемпотентной: проверяйте ключ дедупликации до записи побочных эффектов.

2

Ставить в очередь из продюсера

Замените вызов queue.add() или sqs.sendMessage() на global.durable.startNew(jobName, undefined, payload) и сразу возвращайте ответ.

3

Настроить ретраи и мониторинг

Задайте число попыток и backoff в конфигурации шага пайплайна. Следите за зависшими прогонами в истории выполнения; оповещайте при превышении порога доли сбоев.

Продюсер → консьюмер без Redis и SQS

Продюсер валидирует вход и ставит задачу одним вызовом. Обработчик консьюмера работает в изолированном контейнере с ретраями на стороне платформы.

api/enqueue-export.mjs (продюсер)
export async function handler(event) {
  const { exportId, format } = JSON.parse(event.body || '{}');
  if (!exportId) return { statusCode: 400, body: JSON.stringify({ error: 'exportId required' }) };
  // Replace: queue.add('run-export', { exportId, format })
  const { instanceId: jobId } = await global.durable.startNew('run-export', undefined, { exportId, format: format ?? 'csv' });
  return { statusCode: 202, body: JSON.stringify({ jobId, status: 'queued' }) };
}
jobs/run-export.mjs (консьюмер)
export async function handler(event) {
  const { exportId, format } = event.payload ?? {};
  // Idempotency: skip if already exported
  const existing = await db.findExport(exportId);
  if (existing) return { exportId, fileUrl: existing.url, skipped: true };
  const rows = await fetchExportRows(exportId);
  const fileUrl = await writeExport(rows, format);
  await db.saveExport(exportId, fileUrl);
  await notifyExportReady(exportId, fileUrl);
  return { exportId, fileUrl, rowCount: rows.length };
}

Когда пайплайны Inquir заменяют очередь задач

Когда это уместно

  • Нужны постановка в очередь, ретраи и история прогонов без эксплуатации Redis, SQS или флота воркеров
  • Фоновые задачи должны делить секреты и наблюдаемость с вашим HTTP API

Когда лучше выбрать другое

  • Субмиллисекундная задержка очереди со строгим FIFO на миллионах задач в секунду — для такой пропускной способности и гарантий порядка нужен выделенный брокер сообщений

Частые вопросы

Гарантирует ли Inquir доставку exactly-once?

Нет. Вызовы пайплайнов выполняются at-least-once. Делайте обработчики консьюмера идемпотентными: проверяйте ключ дедупликации (например, exportId, jobId) до записи побочных эффектов, чтобы ретраи были безопасны.

Есть ли dead-letter-очередь?

Да. Очередь durable-задач отправляет задачу в dead-letter после исчерпания попыток и сохраняет последнюю ошибку, чтобы вы могли разобрать и переиграть проблемные сообщения, а не потерять их. Сбои шагов пайплайна дополнительно хранятся в истории выполнения для ручного replay из сохранённого payload.

Можно ставить задачи из обработчиков на Python или Go?

global.durable.startNew() — метод Node.js SDK. Из Python или Go отправьте POST на URL триггера пайплайна с тем же payload — API триггера доступен по HTTP из любого рантайма.

Чем это отличается от BullMQ?

BullMQ выполняет задачи в воркер-процессах, читающих очередь Redis: вы эксплуатируете Redis, масштабируете воркеры и разбираете DLQ. Шаги пайплайна Inquir работают в изолированных контейнерах под управлением платформы. Вы пишете обработчик консьюмера; планирование, ретраи и записи прогонов берёт на себя платформа.