W przypadku zadań w tle (pracy, która nie powinna blokować odpowiedzi HTTP), NestJS integruje się z BullMQ (kolejką wspieraną przez Redis) za pośrednictwem @nestjs/bullmq. Dodajesz zadania do kolejki i przetwarzasz je asynchronicznie w osobnych workerach — utrzymując żądania szybkie i niezawodnie obsługując ciężką lub odroczoną pracę.
Dlaczego to ważne
Some work is too slow or shouldn't block the request:
✗ sending emails, processing images/video, generating reports, calling slow APIs
→ doing it inline makes the user wait and risks timeouts/failures
✓ QUEUE the work → respond immediately → a worker processes it in the background
Konfiguracja kolejki
@Module({
imports: [
BullModule.forRoot({ connection: { host: "localhost", port: 6379 } }), // Redis
BullModule.registerQueue({ name: "email" }), // a named queue
],
})
export class AppModule {}
Dodawanie zadań do kolejki (producent)
@Injectable()
export class NotificationService {
constructor(@InjectQueue("email") private emailQueue: Queue) {}
async register(user: User) {
await this.saveUser(user);
// queue the email INSTEAD of sending it inline → respond to the user immediately
await this.emailQueue.add("welcome", { userId: user.id }, {
attempts: 3, // retry up to 3 times on failure
backoff: { type: "exponential", delay: 5000 },
delay: 60000, // optionally delay the job
});
}
}
Producent dodaje zadanie (z opcjami takimi jak ponowne próby, backoff, opóźnienie) i zwraca się natychmiast — użytkownik nie czeka na wysłanie wiadomości e-mail.
Przetwarzanie zadań (worker/konsument)
@Processor("email")
export class EmailProcessor extends WorkerHost {
async process(job: Job) {
switch (job.name) {
case "welcome":
await this.sendWelcomeEmail(job.data.userId); // the actual work, in the background
break;
}
}
}
Worker @Processor konsumuje zadania z kolejki i wykonuje rzeczywistą pracę asynchronicznie — oddzielnie od cyklu żądanie/odpowiedź (i może nawet działać w osobnym procesie).
Co zapewniają kolejki
✓ Async processing — offload slow work, respond to users instantly
✓ Retries & backoff — failed jobs retry automatically (reliability)
✓ Delayed/scheduled jobs — run work later or on a schedule (repeatable jobs)
✓ Rate limiting & concurrency control — bound how fast/many jobs run
✓ Persistence (via Redis) — jobs survive restarts; not lost if the app crashes
✓ Decoupling — producers and workers scale independently
Dlaczego to ważne
Przetwarzanie zadań w tle za pomocą kolejek jest niezbędne do budowania niezawodnych, responsywnych i skalowalnych back-endów — a zrozumienie integracji BullMQ w NestJS jest ważną wiedzą na poziomie senior.
Podstawową wartością jest delegowanie pracy, która nie powinna blokować odpowiedzi HTTP: wysyłanie e-maili, przetwarzanie obrazów/wideo, generowanie raportów, synchronizacja danych lub wywoływanie wolnych usług zewnętrznych.
Wykonywanie takiej pracy bezpośrednio zmusza użytkowników do czekania, grozi przekroczeniem limitu czasu żądania i straceniu pracy w przypadku błędu — natomiast umieszczenie jej w kolejce pozwala na natychmiastową odpowiedź, podczas gdy background worker przetwarza ją niezawodnie.
Poza asynchronicznym delegowaniem, kolejki zapewniają krytyczne funkcje produkcyjne: automatyczne ponowne próby z backoffem (odporność na przejściowe błędy), opóźnione i zaplanowane zadania, kontrolę współbieżności/ograniczenia szybkości oraz trwałość (zadania wspierane przez Redis przetrwają awarie/ponowne uruchomienia, więc praca nie zostanie utracona).
Również decentralizują producentów od konsumentów, umożliwiając niezależne skalowanie.
Wiedza na temat konfiguracji kolejek, dodawania zadań z odpowiednimi opcjami (ponowne próby, opóźnienia) i przetwarzania ich w workerach jest cenna do projektowania rzeczywistych aplikacji, które elegancko obsługują ciężką lub odroczoną pracę.
To jest powszechny, ważny wzorzec w produkcyjnych systemach NestJS i odzwierciedla dojrzałe zrozumienie budowania responsywnych, niezawodnych back-endów, które wykraczają poza prostą obsługę żądanie-odpowiedź.
