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.
Senin yaşadığın şey klasik: iş sürekli aynı yerde patlıyor, Laravel “tekrar deneyeyim” diyor, tekrar patlıyor, kuyruk ilerleyemiyor. Döngüyü kırman gerekiyor.
- Retry’ı sınırla. İşin üstüne
tries(ya damaxExceptions) ve birbackoffkoy. 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. failed_jobssenin yerleşik DLQ’n. Sınır dolunca Laravel işi otomatikfailed_jobstablosuna taşır — ekstra bir altyapı kurmana gerek yok, Dead Letter Queue zaten budur. İşin üstünefailed()metodu tanımlayıp temizlik/telafi mantığını oraya koy.- Alert kur. Bir
JobFailedlistener’ı yaz; 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 sonraqueue:retryile düzeltilen işi replay edersin. - Fatal Error’ı ayrı ele al. 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. - Kuyrukları riske göre ayır, işleri idempotent yap. Riskli iş tiplerini ayrı bir kuyrukta çalıştır ki tek bir kötü iş tüm diğerlerini aç bırakmasın. Ayrıca işleri idempotent yaz; 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 verme; sınırsız retry, tek bir zehirli mesajı tüm sistemi durduran bir silaha çevirir.
İlgili Yazılar
Yorumlar
Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.