İçeriğe geç
Muhammet Şafak
en
Soran: Tunç Cevaplandı:

Üçüncü parti API bağımlılığında Circuit Breaker'ı nasıl kurarım?


Soru

Uygulamamız kargo fiyatını harici bir kargo API'ından çekiyor. Kargo firması yavaşlayınca ya da çökünce isteklerimiz timeout'a düşüyor, Octane/PHP-FPM worker'ları bloke oluyor ve tüm sistem kilitleniyor. Bu zincirleme çökmeyi önlemek için Circuit Breaker'ı Guzzle middleware veya Go kütüphanesiyle nasıl kurarım? Devre Açık/Kapalı/Yarı-Açık durumlarında sistem nasıl davranmalı?

Cevap

Kısa cevap: Circuit breaker tek başına sizi kurtarmaz — onu agresif bir timeout ile birlikte kurarsanız kurtarır. Çünkü worker’larınızı öldüren şey hatanın kendisi değil, o hataya kadar geçen 30 saniyelik bekleme.

Kısa cevap

Yaşadığınız şey klasik zincirleme çökme (cascading failure): yavaş bir bağımlılık, her isteği timeout’a kadar bekletir, havuz dolar, sistem kilitlenir. Breaker’ın işi, çöken bir bağımlılığı çağırmayı tamamen kesmek. Worker’ın istekler arasında ayakta kaldığı bir mimaride bunun neden daha sert vurduğunu Laravel Octane yazısında anlatmıştım.

Neden

  1. Sizi öldüren hata değil, bekleme. Bağımlılık hızlı hata dönseydi worker anında serbest kalırdı; 30 saniyelik timeout havuzu doldurur.

  2. Breaker’ın üç durumu bir protokoldür. CLOSED: çağrılar geçer, hatalar sayılır. Eşik aşılınca OPEN: bağımlılığı hiç çağırma, anında fallback dön, bir süre (cooldown) böyle kal. Cooldown bitince HALF-OPEN: birkaç deneme isteğini içeri al — başarılıysa CLOSED’a dön, yine hata varsa tekrar OPEN’a geç.

  3. Tek bir bağımlılık tüm havuzu tüketmemeli. İzolasyon olmadan kargo API’nin yavaşlığı sepet ve ödemeyi de aşağı çeker.

Ne yapmalı

  1. Önce timeout’u kısın, asıl katil o. connect_timeout ve timeout’u saniyeler değil milisaniyeler seviyesinde tutun (örn. 800ms-2s). Kısa timeout olmadan breaker işe yaramaz.

  2. Breaker’ı üç durumuyla kurun. Yukarıdaki CLOSED/OPEN/HALF-OPEN döngüsü; eşik ve cooldown değerlerini gerçek hata oranınıza göre seçin.

  3. Bulkhead ile o bağımlılığı izole edin. Kargo API’ye aynı anda gidebilecek istek sayısını sınırlayın; o servis yavaşladığında sadece ona ayrılmış küçük bir dilim tükensin.

  4. Fallback’i önceden tanımlayın. Son cache’lenmiş kargo fiyatını dönün, olmuyorsa “tahmini ücret şu an hesaplanamıyor” deyin. Hata sayfası yerine bozulmuş ama çalışan bir deneyim sunun.

  5. Aracı doğru seçin. Laravel’de Guzzle client’ını bir middleware’e sarın, durumu Redis’te tutun. Go’da elle yazmayın — sony/gobreaker zaten bu üç durumu veriyor.

Sonuç: Ben olsam breaker’ı asla yalnız bırakmam: kısa timeout + bulkhead + cache’li fallback üçlüsüyle kurarım. Worker’ların timeout beklerken bloke olması özellikle kalıcı süreçli mimaride (Octane) çok daha sert vurur; o yüzden önce timeout’u kısın, sonra breaker’ı ekleyin.

İ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