Senior #bullmq#queue#redis#background-jobs
Xử lý job nền với BullMQ trong NestJS: retry, idempotency và scale worker
⚡ Trả lời nhanh
@nestjs/bullmq dùng Redis làm broker: producer inject Queue và add job, consumer là class @Processor extends WorkerHost. Cấu hình attempts/backoff để retry, removeOnComplete để dọn, và thiết kế handler idempotent vì job có thể chạy lại (at-least-once). Scale bằng nhiều worker và concurrency.
BullModule.registerQueue({ name: 'email' }); // trong module
@Injectable()
export class MailProducer {
constructor(@InjectQueue('email') private q: Queue) {}
send(userId: number) {
return this.q.add('welcome', { userId }, {
jobId: `welcome:${userId}`, // chống trùng
attempts: 5, backoff: { type: 'exponential', delay: 1000 },
removeOnComplete: 1000, removeOnFail: false,
});
}
}
@Processor('email', { concurrency: 10 })
export class MailConsumer extends WorkerHost {
async process(job: Job<{ userId: number }>) {
await this.mail.sendWelcome(job.data.userId); // phải idempotent
}
}
- Giao hàng at-least-once: job có thể chạy lại (retry, worker chết giữa chừng) nên cần idempotency key hoặc kiểm tra trạng thái trước khi gửi.
- Job bị kẹt (stalled) được tự đưa lại hàng đợi; xử lý chậm quá thì cần tăng lock hoặc chia nhỏ.
- Job trì hoãn/định kỳ:
delay,repeat(cron) hoặc job scheduler. - Tách worker thành process riêng (không phục vụ HTTP) để scale độc lập và không tranh CPU với API.
- Lắng nghe
failedđể cảnh báo; dead-letter bằng cách giữ job fail để xem lại.