Back to Blog

BullMQ

February 18, 20263 min
BullMQBackground JobsDistributed Systems
BullMQ

BullMQ

BullMQ Nedir?

BullMQ, Node.js uygulamalarında zaman alan, kullanıcıyı bekletmemesi gereken ve retry gerektiren işlemleri arka planda çalıştırmak için kullanılan Redis tabanlı bir job queue sistemidir.

Kullanım amacı:

“Bu işlemi yapmam gerekiyor ama kullanıcıyı bekletemem.”

Örnek senaryolar:

  • E-posta gönderimi
  • Video işleme
  • PDF / rapor oluşturma
  • Büyük dosya yükleme
  • Toplu bildirim gönderimi
  • Ödeme sonrası async işlemler

Neden Direkt API İçinde Yapmayız?

Node.js single-thread mimariye sahiptir. Eğer ağır bir işlemi request içinde yaparsak:

  • Kullanıcı uzun süre response bekler
  • Aynı anda gelen diğer istekler bloklanabilir
  • CPU %100 olabilir
  • Server restart olursa işlem kaybolur

BullMQ bu problemleri çözer.

Neden BullMQ Kullanırız?

BullMQ’nun sağladıkları:

  • Redis tabanlı (in-memory, hızlı)
  • At-least-once delivery
  • Retry & backoff
  • Delayed jobs
  • Rate limiting
  • Worker separation
  • Concurrency kontrolü
  • Atomic operations

Mimari

API Server → Queue (Redis) → Worker
BileşenGörevi
ProducerJob üretir (API)
QueueRedis üzerinde job saklar
WorkerJob’u işler
JobYapılacak iş
RetryHata sonrası tekrar
DelayGecikmeli job
BackoffRetry aralığı
Rate LimitJob hız limiti

Producer – Queue – Worker Nasıl Çalışır?

1. Producer

API içindeki kod job oluşturur ve kuyruğa ekler.

Örneğin: “Bu kullanıcıya hoş geldin maili atılacak.”

2. Queue (Redis)

  • Job’ları saklar
  • Sıralar
  • Hangi job bekliyor, hangisi tamamlandı takip eder

3. Worker

  • Arka planda çalışır
  • Queue’yu dinler
  • Job geldiğinde gerçek işlemi yapar

Önemli Özellikler

Retry (Tekrar Deneme)

Mail servisi kapalıysa:

  • 3 kez dene
  • 5 saniye arayla dene

Delayed Jobs

  • “24 saat sonra hatırlatma maili gönder.”

Priority

  • VIP kullanıcıların işleri önce işlensin.

Concurrency

  • Worker aynı anda kaç job işlesin?
  • Örneğin 5 video paralel işlenebilir.

Örnek Kullanım

Producer

const myQueue = new Queue('mail-queue', { connection: redisConnection });

await myQueue.add('welcome-email', 
  { userId: 1, email: 'test@test.com' }, 
  {
    attempts: 3,
    backoff: 5000
  }
);

Worker

const worker = new Worker(
  'mail-queue',
  async job => {
    console.log(`Sending email to ${job.data.email}`);
  },
  { connection: redisConnection }
);

E-Commerce Örneği

// queue.js
export const orderQueue = new Queue('orderQueue', {
  connection: { host: 'localhost', port: 3003 }
});
// timeout-worker.js
const worker = new Worker(
  'orderQueue',
  async (job) => {
    const { orderId } = job.data;
    await OrderService.cancelIfNotPaid({ orderId });
  },
  { connection: { host: 'localhost', port: 3003 } }
);

Örnek senaryo:

  • Kullanıcı sipariş verdi
  • 15 dakika ödeme yapmazsa sipariş iptal edilecek
  • Bu işlem background job ile yapılır

Redis Neden Kullanılır?

  • In-memory → Çok hızlı
  • Atomic operations → Race condition engellenir
  • Distributed lock mantığı sağlar
  • Multiple worker güvenli şekilde çalışabilir

Bir job’un iki worker tarafından aynı anda işlenmesini Redis engeller.

BullMQ Kullanmazsak Ne Olur?

  • Kullanıcı response bekler
  • CPU yükselir
  • Server restart olursa job kaybolur
  • Retry mekanizması olmaz
  • İşler sessizce fail olabilir

Monitoring Neden Şart?

Background job’lar:

  • Request’e bağlı değildir
  • Sessizce fail olabilir
  • Kullanıcı fark etmeyebilir

Monitoring yoksa problem fark edilmez.

BullMQ Dashboard (Arena)

npm install bull-arena
app.use(
  "/bullmq-dashboard",
  Arena(
    {
      BullMQ: require("bullmq"),
      queues: [{ name: "testQueue", hostId: "Main Server" }],
    },
    { basePath: "/bullmq-dashboard", disableListen: true }
  )
);

Dashboard üzerinden:

  • Bekleyen job’lar
  • Başarılı job’lar
  • Fail olan job’lar
  • Retry sayıları

görülebilir.

Message Queue Kavramı

RolAçıklama
ProducerMesajı üretir
BrokerMesajı saklar ve iletir (Redis)
ConsumerMesajı işler

Bu yapı sadece BullMQ değil, Kafka ve RabbitMQ gibi sistemlerde de geçerlidir.