BullMQ i Job Queues w Node.js
BullMQ (Redis, priority, flows, rate limiter), Inngest (serverless), Trigger.dev i Temporal — background jobs poza request-response.
6 rozwiązań job queue — porównanie
BullMQ, Inngest, Trigger.dev, Qstash, Temporal i pg-boss — backend, hosting i zastosowanie.
| Rozwiązanie | Backend | Hosting | Kiedy |
|---|---|---|---|
| BullMQ | Redis | Self-hosted | Pełna kontrola, Redis available, complex workflows |
| Inngest | Managed (Inngest) | SaaS + self-hosted | Serverless, Next.js, zero Redis infra |
| Trigger.dev | PostgreSQL | SaaS + self-hosted | Event-driven, self-hosted opcja |
| Qstash (Upstash) | Redis + HTTP | SaaS (Upstash) | Serverless, Vercel, HTTP-based queue |
| Temporal.io | Temporal server | Self-hosted/Cloud | Long-running workflows, saga patterns |
| pg-boss | PostgreSQL | Self-hosted (Postgres) | Postgres-only, prostsze niż BullMQ |
Często zadawane pytania
Co to jest BullMQ i dlaczego job queues są ważne?
BullMQ: zaawansowana biblioteka job queue dla Node.js. Oparta na Redis. Następca Bull.js. Dlaczego job queues: operacje asynchroniczne poza request-response. Email sending, image processing, PDF generation. Nie blokuj HTTP response. Retry logic — automatyczne ponowienia. Scheduled jobs — crony w kodzie. Rate limiting — nie przeciąż zewnętrznych API. Instalacja: npm install bullmq ioredis. Tworzenie kolejki: import {Queue, Worker} from 'bullmq'. const connection = {host: 'localhost', port: 6379}. const emailQueue = new Queue('email', {connection}). Dodawanie zadań: await emailQueue.add('send-welcome', {userId: '123', email: 'user@example.com'}). Options: delay: 5000 (ms). priority: 1 (wyższy = wcześniej). attempts: 3 (retry). backoff: {type: 'exponential', delay: 1000}. removeOnComplete: 100 (zachowaj 100 ukończonych). removeOnFail: false. Worker: const worker = new Worker('email', async (job) => { await sendEmail(job.data.email, 'Welcome!'). return {sent: true} }, {connection, concurrency: 5}). worker.on('completed', (job, result) => console.log(job.id, result)). worker.on('failed', (job, err) => console.error(job.id, err)). Bull Dashboard (BullBoard): @bull-board/api + @bull-board/express. Wizualizacja kolejek. Retry zadań z UI. Monitorowanie. Innymi słowy — kolejki to jak asynchroniczne mikroserwisy wewnątrz monolitu.
BullMQ — zaawansowane funkcje: priorytety, flows i rate limiting?
Priority queues: każde zadanie ma priority. Wyższy numer = niższy priorytet (jak Linux niceness). addBulk z różnymi priorytetami. const urgentQueue = new Queue('tickets', {defaultJobOptions: {priority: 1}}). await urgentQueue.add('ticket', data, {priority: 1}). Flows (Job graphs): zależności między zadaniami. import {FlowProducer} from 'bullmq'. const flow = new FlowProducer({connection}). await flow.add({name: 'send-email', queueName: 'email', data: {to: user.email}, children: [{name: 'generate-pdf', queueName: 'pdf', data: {invoiceId: '123'}}]}). Parent czeka na dzieci. Rate Limiter: worker z ratelimiter. limiter: {max: 100, duration: 60000} — 100 req/min. Throttling zewnętrznych API. Prevent 429 errors. Repeatable Jobs (Cron): await queue.add('daily-report', {}, {repeat: {cron: '0 8 * * *'}}). await queue.add('every-5min', {}, {repeat: {every: 5 * 60 * 1000}}). Zarządzanie repeatables. Sandboxed processors: osobny process per worker. Izolacja błędów. Lepsza dla CPU-intensive. processor: './worker-process.js'. Job Data size: nie przechowuj dużych danych w job. Referencja (ID do DB) zamiast danych. Redis nie jest bazą danych. Events: queue.on('waiting'), queue.on('active'). worker.on('progress') — job.updateProgress(50). QueueEvents.on('completed'). Testowanie BullMQ: jest + testcontainers Redis. Lub mockowanie Queue i Worker. Integration tests z prawdziwym Redis (docker).
Redis jako backend dla BullMQ — konfiguracja i monitoring?
Redis dla BullMQ: ioredis pod spodem. Sentinel support dla HA. Cluster mode. TLS. Konfiguracja Redis: const connection = new IORedis({host: process.env.REDIS_HOST, port: 6379, password: process.env.REDIS_PASSWORD, maxRetriesPerRequest: null, enableReadyCheck: false}). maxRetriesPerRequest: null — wymagane przez BullMQ. Redis Cloud: Upstash Redis — serverless, per-request billing. Redis Enterprise. AWS ElastiCache (Redis). Dobry dla: serverless functions z BullMQ. Upstash + Vercel. BullMQ w Next.js: Route Handler do tworzenia zadań. Worker jako osobny proces (server.ts). Nie w Next.js serverless functions (long-running). Lub: Trigger.dev zamiast. Trigger.dev: managed job queue. Bez własnego Redis. Background jobs w Next.js bez infrastruktury. TypeScript natywny. Qstash (Upstash): serverless message queue. HTTP-based. Schedules. Delay. Bez Redis klienta. Inngest: background jobs + workflows. Event-driven. Zero infrastructure. TypeScript. Monitoring: BullBoard: @bull-board/express. /admin/queues. Metryki: zaległe, aktywne, ukończone, nieudane. Retry z UI. Prometheus exporter: bullmq-prometheus. Grafana dashboard. Alerty przy stuck jobs. Redis monitoring: Redis Commander, RedisInsight. Memori i eviction policy. allkeys-lru dla cache. noeviction dla queues.
Inngest i Trigger.dev — managed background jobs bez Redis?
Inngest: event-driven background jobs. Bez własnego Redis/infrastruktury. TypeScript-first. Serverless compatible. Instalacja: npm install inngest. SDK: import {Inngest} from 'inngest'. const inngest = new Inngest({id: 'my-app'}). Function: const sendWelcomeEmail = inngest.createFunction({id: 'send-welcome-email'}, {event: 'user/signed.up'}, async ({event, step}) => { await step.run('send-email', async () => { await sendEmail(event.data.email) }). await step.sleep('wait-3-days', '3 days'). await step.run('send-followup', async () => { await sendFollowup(event.data.email) }) }). Steps: automatyczny retry per step. Durability — nie od początku. Widoczność stanu w dashboard. Trigger event: await inngest.send({name: 'user/signed.up', data: {email: user.email}}). Next.js integration: serve({client: inngest, functions: [sendWelcomeEmail]}) w /api/inngest. Inngest dev server: npx inngest-cli@latest dev. Dashboard lokalny. Trigger.dev: podobny do Inngest. Zadania jak długorunning funktory. await wait(). await io.runTask(). PostgreSQL jako backend. Self-hosted opcja. Temporal.io: bardziej zaawansowany. Workflow orchestration. Durable execution. Go/Java/Python/TS SDK. Dla złożonych, długorunning workflows. Cadence (Uber): poprzednik Temporal. Workflow patterns: Fire and forget. Request-response z polling. Saga compensation. Parallel fan-out. State machine workflow. Kiedy BullMQ vs Inngest: BullMQ — pełna kontrola, Redis available. Inngest — serverless, nie chcesz Redis.
Praktyczne zastosowania job queues — email, image processing i raporty?
Email sending: transactional emails (welcome, invoice). Nie blokuj HTTP response. addJob('send-email', {to, subject, template, data}). Worker wysyła przez Resend/Nodemailer. Retry przy błędzie SMTP. Image processing: upload -> S3 -> queue job. Worker: pobranie z S3. sharp: resize, webp, optimize. Upload back to S3. Powiadom frontend (WebSocket/polling). PDF generation: invoice -> queue. Puppeteer server-side. @react-pdf/renderer. Zapisz do S3. Email z linkiem. Background sync: sync z zewnętrznym API. Schedule co 15 min. Rate limit: nie przeciążaj external. Store results w bazie. Powiadomienia push: WebPush API. Scheduled notifications. Batch sends. Delayed: send after 1h idle. Web scraping: kolejka URL do scrape. Rate limit na domain. Retry 429. Store results. Data processing: ETL jobs. Import CSV. Transformacja. Validation. Save do DB. Report generation: complex aggregations. Scheduled (cron midnight). Cache results. Notify user gdy gotowe. Webhooks reliability: retry przy błędzie. Exponential backoff. Exactly-once semantics: idempotency key. Redis SETNX. Job data zawiera idempotencyKey. Worker sprawdza przed wykonaniem. Monitoring SLAs: queue depth alert. Job age alert. Failed rate alert. Grafana + Prometheus + BullMQ stats. Dead Letter Queue: po max retries. Manual review. Re-queue lub discard. Alerting przy DLQ.
Powiązane artykuły
Skontaktuj się z nami
Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.
Wyślij zapytanie
Telefon
+48 790 814 814
Pon-Pt: 9:00 - 18:00
adam@fotz.pl
Odpowiadamy w ciągu 24h
Adres
Plac Wolności 16
61-739 Poznań
Godziny pracy
Wolisz porozmawiać?
Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.
Zadzwoń teraz