Oyun Kitabı
Ödeme Worker'ları İçin Retry Algoritmaları (Odeme Workerlari İcin Retry Algoritmalari)
Exponential backoff, jitter, cap, defer ile retry farkı ve circuit breaker — bir önceki bölümdeki taksonomiyi çalışan koda dönüştürün.
Dağıtık Ödeme Motoru (Distributed Payment Engine)
Bolum 12 / 22
Capture ile complete arasındaki boşluğu kapatan dağıtık ödeme mimarisi serisi.
Önceki bölümde dört hata kategorisi tanımladık. Bu bölüm, retry uygun olan üç kategori (timeout sonrası sorgu, rate limited, infrastructure) için gerçek algoritmayı kuruyor: ne kadar bekleyeceğiz, kaç kez deneyeceğiz, ne zaman tamamen durup circuit breaker'ı açacağız?
Attempt 1 → başarısız → bekle (backoff) → Attempt 2
→ başarısız → bekle (daha uzun) → Attempt 3
→ başarısız → cap'e ulaşıldı → defer / dead-letter
Burada iki farklı fiil birbirine karışmamalı: retry aynı worker içinde hemen tekrar deneme; defer ise işi bir süre bekletip daha sonra yeniden kuyruğa koyma. İkisi de 'tekrar dene' gibi görünür ama zamanlama ve sorumluluk farklıdır.
Kavramlar ilk geçtiği yerde
📦 Exponential Backoff
Her denemede bekleme süresini katlayarak artıran strateji: base * 2^attempt.
📦 Jitter
Backoff süresine eklenen rastgele sapma; çok sayıda worker'ın aynı anda tekrar denemesini (thundering herd) önler.
📦 Cap
Bekleme süresinin ve/veya deneme sayısının üst sınırı; sonsuz retry döngüsünü engeller.
📦 Circuit Breaker
Bir bağımlılık sürekli başarısız olduğunda istekleri tamamen durduran, zamanla yeniden deneyen koruma mekanizması.
Jitter'sız backoff, aynı anda başarısız olan yüzlerce işin aynı milisaniyede tekrar denemesine yol açar — bu, zaten zorlanan PSP'yi daha da kötü bir duruma sokar.
Backoff formülü ve neden sabit bekleme yetmez
Sabit 1 saniyelik bekleme basittir ama iki sorunu vardır: PSP kısa süreli bir yoğunluktan geçiyorsa 1 saniye yetmeyebilir; PSP zaten toparlandıysa 1 saniye gereksiz yavaşlıktır. Exponential backoff, ilk denemelerde hızlı, sonraki denemelerde daha temkinli olur:
delay = min(cap, base * 2^attempt) + random(0, jitterRange)
attempt 0 → ~200ms
attempt 1 → ~400ms
attempt 2 → ~800ms
attempt 3 → ~1600ms
...
attempt N → cap'e ulaşır (örn. 30s)
Jitter eklenmeden bu formül tehlikelidir: aynı anda başarısız olan tüm worker'lar tam olarak 200ms, 400ms, 800ms sonra tekrar dener ve senkron dalgalar halinde PSP'yi vurur. Rastgele bir miktar eklemek (full jitter veya decorrelated jitter) bu dalgayı yayar.
Retry ile defer arasındaki fark
Retry, worker aynı process içinde, kısa bir bekleme sonrası aynı isteği tekrar dener — genellikle saniyeler içinde. Defer, işin veritabanına veya kuyruğa geri konup belirli bir süre sonra (dakikalar, hatta saatler) yeniden ele alınmasıdır. Rate limited bir hata genellikle retry ile çözülür; ama PSP'nin kendisi geniş çaplı bir kesinti yaşıyorsa, dakikalarca retry döngüsünde kalmak worker'ı ve kaynakları tüketir — bu noktada defer, işi bir süre 'uyutmanın' daha sağlıklı yoludur.
Rate limited → retry (saniyeler, backoff ile)
Uzun süreli PSP kesintisi → defer (dakikalar, ayrı bir zamanlanmış tekrar)
Circuit breaker: ne zaman denemeyi tamamen durdurmalı
Bir bağımlılığa yapılan istekler art arda başarısız olduğunda, her yeni istek zaten bilinen bir sonucu tekrar üretmekten başka bir şey yapmaz; sadece kaynak tüketir ve gecikmeyi büyütür. Circuit breaker üç durumla çalışır:
Closed → istekler normal şekilde gönderilir
│ hata eşiği aşıldı
▼
Open → istekler hemen reddedilir, PSP'ye hiç gitmez
│ soğuma süresi geçti
▼
Half-Open → sınırlı sayıda deneme istek gönderilir
├─ başarılı → Closed
└─ başarısız → Open
Circuit breaker, retry'ın yerini almaz; retry'ın israf ürettiği anı erken tespit eden bir üst katmandır. Breaker açıkken worker'lar deferred kuyruğa yönlenmelidir, boşuna denemeye devam etmemelidir.
Kaç deneme, ne kadar cap
Bu sayılar keyfi olmamalı; PSP'nin kendi SLA'sı ve işin iş değeri ile orantılı olmalıdır. Yüksek değerli bir ödeme için 8-10 deneme ve 5 dakikalık toplam pencere makul olabilir; düşük öncelikli bir arka plan işlemi için 3 deneme yeterli olabilir.
Sık karıştırılan ayrımlar
❌ Retry = defer
✓ Retry saniyeler içinde aynı process'te olur; defer işi dakikalarca bekletir
❌ Jitter isteğe bağlı bir iyileştirmedir
✓ Jitter'sız backoff, thundering herd riskini gerçek hale getirir
❌ Circuit breaker retry'ın alternatifidir
✓ Circuit breaker, retry'ı ne zaman durduracağını söyleyen üst katmandır
Full jitter ile jitter'sız backoff karşılaştırması
| Kriter | Jitter'sız | Full jitter |
|---|---|---|
| Senkron dalga riski | Yüksek | Düşük |
| PSP üzerindeki yük deseni | Ani zirveler | Dağılmış |
| Uygulama karmaşıklığı | Düşük | Az daha yüksek |
Retry algoritmasını kurarken kontrol listesi
- Backoff formülünde bir cap var mı, yoksa bekleme süresi teorik olarak sonsuza kadar büyüyebilir mi?
- Jitter uygulanıyor mu, yoksa tüm worker'lar aynı anda mı tekrar deniyor?
- Rate limited ile uzun süreli kesinti arasında retry/defer ayrımı yapılıyor mu?
- Circuit breaker açıkken worker'lar gerçekten PSP'ye istek göndermeyi durduruyor mu?
- Deneme sayısı ve toplam pencere, işin gerçek iş değerine göre mi belirlendi, yoksa rastgele bir sayı mı?
- Circuit breaker'ın açık/yarı açık/kapalı geçişleri metrik olarak izleniyor mu?
Bu yazıdan aklında ne kalmalı
- Exponential backoff tek başına yeterli değildir; jitter olmadan senkron dalgalar üretir.
- Retry ve defer aynı fiil değildir: biri saniyeler içindir, diğeri dakikalar-saatler içindir.
- Circuit breaker retry'ın alternatifi değil, retry'ın ne zaman israf haline geldiğini erken söyleyen bir koruma katmanıdır.
- Deneme sayısı ve cap, işin gerçek değerine göre bilinçli seçilmelidir.
İyi bir retry algoritması, başarısızlığı gizlemez; başarısızlığın maliyetini kontrollü hale getirir.
Bir sonraki bölümde bu retry'ların çalıştığı zemine geçiyoruz: veritabanı destekli iş kuyruğu ve lease mekanizması, aynı işin iki worker tarafından aynı anda işlenmesini nasıl önler?
SSS
Sık sorulan sorular
Exponential Backoff nedir?
Her denemede bekleme süresini katlayarak artıran strateji: base * 2^attempt.
Jitter nedir?
Backoff süresine eklenen rastgele sapma; çok sayıda worker'ın aynı anda tekrar denemesini (thundering herd) önler.
"Retry = defer" doğru mu?
Retry saniyeler içinde aynı process'te olur; defer işi dakikalarca bekletir
Bu bölüm neyi sabitler?
Burada iki farklı fiil birbirine karışmamalı: **retry** aynı worker içinde hemen tekrar deneme; **defer** ise işi bir süre bekletip daha sonra yeniden kuyruğa koyma. İkisi de 'tekrar dene' gibi görünür ama zamanlama ve sorumluluk farklıdır. Exponential backoff tek başına yeterli değildir; jitter olmadan senkron dalgalar üretir. Önceki bölümde dört hata kategorisi tanımladık. Bu bölüm, retry uygun olan üç kategori (timeout sonrası sorgu, rate limited, infrastructure) için gerçek algoritmayı kuruyor: ne kadar bekleyeceğiz, kaç kez deneyeceğiz, ne zaman tamamen durup circuit breaker'ı açacağız?
Ogrenilen Muhendislik Prensipleri
- Jitter'sız backoff, senkron başarısızlık dalgaları üretir.
- Retry saniyelerdir, defer dakikalar-saatlerdir — aynı fiil değildir.
- Circuit breaker, retry'ın israf haline geldiği anı erken durdurur.
Okumaya devam et
Okumaya devam et
Seride sonraki yazi
Lease ile Veritabanı Destekli İşler
Conditional UPDATE ile lease alma, sıkışmış işleri kurtaran watcher ve neden yalnızca mesaj Nack etmek production ödemede yetmez.
Seride sonraki yazi
Ödeme Hata Taksonomisi
Timeout, 429, 5xx, business decline ve infrastructure hatası aynı şey değildir. Her kategori farklı bir retry politikası ister.
Ayni seriden
Ödeme Mutabakat Worker İnşası
Sweeper'lar drift'i nasıl iyileştirir: PSP başarılı derken local kayıt expired olabilir; aged FinalizePending nasıl toparlanır.