Skill de Worker de Fila
Worker BullMQ com retentativas e checklist de DLQ - uma Skill de Agente para processamento assíncrono de jobs no Node.js 24 com Redis.
Busque em todas as páginas da documentação
Worker BullMQ com retentativas e checklist de DLQ - uma Skill de Agente para processamento assíncrono de jobs no Node.js 24 com Redis.
Produz um plano de bootstrap do worker: definição da fila, entrada do processo do worker, schema do payload, política de retentativa/DLQ, hooks de observabilidade e divisão do deploy a partir da API HTTP.
| Entrada | Por quê |
|---|---|
| Nome da fila | email, webhooks-outbound |
| Formato do payload do job | Campos do schema Zod |
| Alvo de concorrência | CPU do pod do worker e limites de taxa upstream |
| URL do Redis | Cluster compartilhado ou Redis dedicado para filas |
| Necessidades de idempotência | Jobs como de pagamento precisam de chaves de dedup |
src/queues/<name>.queue.ts - Produtor da filasrc/workers/<name>.worker.ts - Consumidor do workersrc/schemas/<name>.job.ts - Schema do payload Zodpackage.json: "worker:<name>": "node dist/workers/<name>.worker.js"new Worker() dentro de server.ts HTTP.maxRetriesPerRequest: null em conexões ioredis usadas por workers BullMQ.parse lança exceção → retentativa BullMQ; logar "poison pills".removeOnComplete: true ilimitado - manter os últimos N para depuração.await worker.close() antes de sair para jobs em andamento.jobId, attemptsMade, não PII completo do payload.Cartão de receita de referência rápida - pronto para copiar e colar.
# Verificação após a saída da skill
export REDIS_URL=redis://localhost:6379
npm run build
npm run worker:email &
WORKER_PID=$!
node -e "
import { emailQueue } from './dist/queues/email.queue.js';
const job = await emailQueue.add('send', { to: 'test@example.com', templateId: 'welcome' });
console.log('enqueued', job.id);
"
sleep 5
redis-cli LLEN bull:email:failed # esperar 0 em sucesso
kill -TERM $WORKER_PID// src/schemas/email.job.ts
import { z } from "zod";
export const emailJobSchema = z.object({
to: z.string().email(),
templateId: z.string(),
vars: z.record(z.string()).default({}),
});
export type EmailJob = z.infer<typeof emailJobSchema>;// src/workers/email.worker.ts
import { Worker } from "bullmq";
import { createRedis } from "../redis.js";
import { emailJobSchema } from "../schemas/email.job.js";
import { sendEmail } from "../services/email.js";
const worker = new Worker(
"email",
async (job) => {
const payload = emailJobSchema.parse(job.data);
await sendEmail(payload);
},
{
connection: createRedis(),
concurrency: 5,
}
);
async function shutdown() {
await worker.close();
process.exit(0);
}
process.on("SIGTERM", shutdown);
process.on("SIGINT", shutdown);attempts definido por tipo de job (3-5 típico)backoff: { type: "exponential", delay: 2000 }email-dlq OU retidos no conjunto failedfailed no Redis/Bull BoardUse a Skill de Worker de Fila:
- Fila: webhooks-outbound
- Payload: { url, secret, eventType, body }
- Concorrência: 20
- Idempotência: eventId único no Postgres
- Serviço: notifications-api (Fastify 5)O mesmo repositório funciona bem com npm run worker:* e Deployment K8s separados. Divida pacotes quando as dependências do worker (bibliotecas PDF) inflarem o tamanho da imagem da API.
Alvo abaixo de 30s. Trabalhos mais longos devem fazer checkpoint ou serem divididos em jobs encadeados. A detecção de jobs stalled do BullMQ penaliza o bloqueio da CPU.
Versões da Stack: Esta página foi escrita para Node.js 24.18.0 (LTS Ativo), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 e NestJS 11.
Revisado por Chris St. John·Última atualização: 16 de jul. de 2026