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

> Breaker tek başına yetmez: `connect_timeout` ve `timeout`'u 800ms-2s'ye çekin, bağımlılığı bulkhead ile izole edin, cache'li bir fallback tanımlayın.

- Soruldu: 2026-05-25
- Yanıtlandı: 2026-05-28
- Soran: Tunç
- Etiketler: dayaniklilik, mimari, laravel
- Kaynak: https://www.muhammetsafak.com.tr/sor-bakalim/ucuncu-parti-api-icin-circuit-breaker-deseni/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
**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ı?


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.

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.

1. **Üç durumu doğru kurun.** `CLOSED`: çağrılar geçer, hatalar sayılır. Eşik aşılınca `OPEN`'a geçin: bağımlılığı hiç çağırmayın, anında fallback dönün ve bir süre (cooldown) böyle kalın. Cooldown bitince `HALF-OPEN`: birkaç deneme isteğini içeri alın — başarılıysa `CLOSED`'a dönün, yine hata varsa tekrar `OPEN`'a geçin. Mantığın kalbi bu.
2. **Ö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; ikisini birlikte ayarlayın yoksa havuz yine dolar.
3. **Bulkhead ile o bağımlılığı izole edin.** Kargo API'ye aynı anda gidebilecek istek sayısını sınırlayın. Böylece o servis yavaşladığında tüm worker'larınızı değil, sadece ona ayrılmış küçük bir dilimi tüketir; çekirdek akış (sepet, ödeme) ayakta kalır.
4. **Fallback'i önceden tanımlayın.** Son cache'lenmiş kargo fiyatını dönün, olmuyorsa "tahmini ücret şu an hesaplanamıyor" deyin. Kullanıcıya hata sayfası göstermek 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

- [Laravel Octane: kalıcı süreçle gelen performans](/blog/laravel-octane-kalici-surecle-gelen-performans/) — Blog
- [Kuyrukta poison pill (zehirli mesaj) ve Dead Letter Queue'yu nasıl yönetirim?](https://www.muhammetsafak.com.tr/sor-bakalim/kuyrukta-poison-pill-ve-dead-letter-queue-yonetimi/) — Sor Bakalım
- [Graceful degradation: kritik olmayan servisleri yük altında nasıl izole ederim?](https://www.muhammetsafak.com.tr/sor-bakalim/graceful-degradation-kritik-olmayan-servisleri-izole-etmek/) — Sor Bakalım
- [İşlediğim satırları aynı anda güncellerken chunk yerine chunkById mı kullanmalıyım?](https://www.muhammetsafak.com.tr/sor-bakalim/isledigim-satirlari-ayni-anda-guncellerken-chunk-yerine-chunkbyid-mi-kullanmaliyim/) — Sor Bakalım
