İçeriğe geç
Muhammet Şafak
en
Soran: Gökhan Cevaplandı:

Kuyrukta poison pill (zehirli mesaj) ve Dead Letter Queue'yu nasıl yönetirim?


Soru

Laravel Queue (Redis) üzerinde bir job, üçüncü parti bir kütüphanedeki bug yüzünden her işlendiğinde Fatal Error verip worker'ı çökertiyor. Laravel işi otomatik retry ediyor ve tekrar çöküyor; bu zehirli mesaj tüm kuyruğu bloke ediyor. Bu hatalı mesajları ana kuyruktan ayırıp incelemek üzere Dead Letter Queue'ya taşıyan ve yöneticileri uyaran iş akışını nasıl kurarım?

Cevap

Kısa cevap: Her seferinde patlayan ve sonsuza dek otomatik retry edilen bir iş, kuyruğu kilitleyip worker’ı çökertir — buna poison pill (zehirli mesaj) denir. Çözüm retry’ı sınırlamak ve hatalı işi yeniden kuyruğa atmak yerine bir DLQ’ya düşürmek.

Sizin yaşadığınız şey klasik: iş sürekli aynı yerde patlıyor, Laravel “tekrar deneyeyim” diyor, tekrar patlıyor, kuyruk ilerleyemiyor. Döngüyü kırmanız gerekiyor.

  1. Retry’ı sınırlayın. İşin üstüne tries (ya da maxExceptions) ve bir backoff koyun. Böylece iş 3-5 kez denenir, her seferinde sonsuza dek değil. Belirlenen sınıra ulaşınca Laravel onu yeniden kuyruğa atmayı bırakır.
  2. failed_jobs sizin yerleşik DLQ’nuz. Sınır dolunca Laravel işi otomatik failed_jobs tablosuna taşır — ekstra bir altyapı kurmanıza gerek yok, Dead Letter Queue zaten budur. İşin üstüne failed() metodu tanımlayıp temizlik/telafi mantığını oraya koyun.
  3. Alert kurun. Bir JobFailed listener’ı yazın; iş failed_jobs’a düştüğü an Slack/Sentry’ye bildirim göndersin. “Sessizce başarısız olan iş” en kötü senaryodur; yöneticiler anında haberdar olmalı. İncelemeden sonra queue:retry ile düzeltilen işi replay edersiniz.
  4. Fatal Error’ı ayrı ele alın. Exception değil, worker’ı komple öldüren Fatal Error için Laravel’in normal retry’ı işlemez. Supervisor worker’ı yeniden başlatır ama aynı iş tekrar çekilirse döngü kapanmaz. Bunun için “bu job id’yi N kez gördüm” sayacı (Redis’te) tutup eşiği aşınca işi zorla failed_jobs’a atın.
  5. Kuyrukları riske göre ayırın, işleri idempotent yapın. Riskli iş tiplerini ayrı bir kuyrukta çalıştırın ki tek bir kötü iş tüm diğerlerini aç bırakmasın. Ayrıca işleri idempotent yazın; retry güvenli olsun, iki kez çalışsa da yan etki birikmesin.

Sonuç: Sınırlı retry + failed_jobs DLQ + alert + queue:retry ile replay. Hiçbir işin sınırsız retry edilmesine izin vermeyin; sınırsız retry, tek bir zehirli mesajı tüm sistemi durduran bir silaha çevirir.

İlgili Yazılar

Paylaş:

Yorumlar

Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.

Diğer Sorular

Tüm sorular

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi