Referência: Frota de Workers
Uma frota de workers de referência para Node.js 24: processadores BullMQ, idempotência, monitoramento de dead-letter e concorrência ciente do pool - pareado com Referência: API B2B SaaS.
Busque em todas as páginas da documentação
Uma frota de workers de referência para Node.js 24: processadores BullMQ, idempotência, monitoramento de dead-letter e concorrência ciente do pool - pareado com Referência: API B2B SaaS.
Cartão de receita de referência rápida.
API publica job → Redis (BullMQ) → pod(s) worker → Postgres + HTTP de saída
↓ falhas
fila DLQ + PagerDuty// Padrão de envelope de job
type JobEnvelope<T> = {
idempotencyKey: string;
tenantId: string;
traceparent?: string;
payload: T;
};// src/workers/order-email.worker.ts
import { Worker, Queue } from "bullmq";
import IORedis from "ioredis";
const connection = new IORedis(process.env.REDIS_URL!, { maxRetriesPerRequest: null });
export const orderEmailQueue = new Queue("order-email", { connection });
const worker = new Worker(
"order-email",
async (job) => {
const { idempotencyKey, tenantId, payload } = job.data;
const done = await redis.set(`idem:${idempotencyKey}`, "1", "EX", 86400, "NX");
if (!done) {
job.log("duplicate skipped");
return;
}
await sendEmail(tenantId, payload);
},
{
connection,
concurrency: 5, // pool max 20 no worker; API usa 10
},
);
worker.on("failed", async (job, err) => {
if (job && job.attemptsMade >= 3) {
await dlq.add("failed", { original: job.data, error: String(err) });
}
});// src/main-worker.ts - desligamento gracioso
import { orderEmailWorker } from "./workers/order-email.worker";
async function shutdown(signal: string) {
console.info({ msg: "shutdown", signal });
await orderEmailWorker.close();
process.exit(0);
}
process.on("SIGTERM", () => shutdown("SIGTERM"));| Métrica | Alerta |
|---|---|
bullmq_queue_waiting | > 1000 por 10m |
bullmq_dlq_depth | > 0 por 15m |
job_duration_p95 | > 30s |
pg_pool_waiting | > 0 por 5m no worker |
pool max no worker = 20
concorrência = 5 (não 20 - jobs fazem 2-4 consultas cada)
pool max da API = 10 (Implantação separada)max_connections do Postgres{tenantId}:{event}:{entityId} ex: acme:order-email:ord_123processed_jobs para finanças1. Alerta dispara na profundidade da DLQ
2. Plantão inspeciona os 5 primeiros jobs no Bull Board
3. Corrige a causa raiz (bug no template, 403 do fornecedor)
4. Reenvia a DLQ para a fila primária em lotes de 50
5. Pós-mortem se os e-mails do cliente perderam o SLAworker.worker.close() no desligamento (ver Desligamento Gracioso).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