Inquir Compute · job queue

Serverless job queue: уберите Redis и флот воркеров

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

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

Суть ответа

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

Когда подходит и когда нет

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

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

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

Во что обходится эксплуатация продакшен-очереди задач

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

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

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

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

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

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

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

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

Queue operational ownership comparison

What you own and operate for each approach—not a feature comparison, an operational one.

Queue operational ownership comparison
Ownership areaBullMQ + RedisAWS SQS + LambdaInquir Pipelines
Queue infrastructureRedis cluster (you provision)SQS queue (AWS managed)None—built into pipeline
Worker processBullMQ workers (you run)Lambda consumer (you configure)Pipeline steps (platform runs)
Retry configPer-job in worker codeRedrive policy + DLQPer-step in pipeline config
Run history / observabilityRedis keys (short TTL)CloudWatch + DLQ inspectionExecution records (30-day retention)
Secrets modelSeparate from HTTP routesIAM + Secrets ManagerShared workspace secrets
Delivery guaranteeAt-least-once with RedisAt-least-once with SQSAt-least-once (no guaranteed ordering)

Паттерны job queue в Inquir

Enqueue из любого продюсера

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

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

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

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

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

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

Шаг задачи вызывает global.durable.startNew() N раз для параллельных дочерних пайплайнов. Никакого отдельного queue-продукта или конфига topic fanout.

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

1

Написать хендлер консьюмера

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

2

Enqueue из продюсера

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

3

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

Задайте число попыток и backoff в конфиге шага пайплайна. Отслеживайте зависшие прогоны в истории выполнения и оповещайте при превышении порога failure rate.

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

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

api/enqueue-export.mjs (producer)
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 (consumer)
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 заменяют job queue

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

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

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

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

Вопросы и ответы

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

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

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

Отдельной DLQ-инфраструктуры нет. Когда шаг исчерпывает политику ретраев, прогон пайплайна помечается failed с полными логами шагов в истории выполнения. Оповещайте по failure rate; делайте replay из сохранённого payload вручную или запускайте новый прогон.

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

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

Как это сравнивается с BullMQ конкретно?

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