Yazılar

Circuit Breaker Nedir? Cascading Failure (Zincirleme Çöküş) ve Fail-Fast Mimarisi

Dağıtık sistemlerde tek bir servisin yavaşlaması neden tüm sistemi domino taşı gibi çökertir? Thread Pool Exhaustion, Cascading Failure ve Circuit Breaker (Closed, Open, Half-Open) deseni.

Furkan Özay29 Ekim 2026 · 4 dk okuma
czCZAY.DEV // EDITORIALTR
SYSTEM ARCHITECTURE

#System Design · 4 DK OKUMA

FURKAN ÖZAYVOL. 2026 // #127E

Dağıtık sistemlerde ve mikroservis mimarilerinde en tehlikeli senaryo bir servisin tamamen çökmesi değil, yavaşlamasıdır. Tamamen çöken bir servis anında bağlantı hatası (Connection Refused) döner ve kaynakları serbest bırakır; ancak yavaşlayan bir servis, kendisini çağıran tüm sistemleri sessizce boğar.

Yavaşlayan Servis Tuzağı ve Cascading Failure

Bir e-ticaret sisteminde ödeme veya kargo servisinin normalde 150ms olan yanıt süresinin, veritabanı kilitlemesi veya ağ darboğazı yüzünden 15 saniyeye çıktığını düşünelim.

  1. Thread Pool Exhaustion (İş Parçacığı Havuzunun Tükenmesi): API Gateway veya sipariş servisi, gelen her kullanıcı isteği için bir worker thread (veya bağlantı) ayırır ve yavaşlayan servisin yanıtını beklemeye başlar.
  2. Kuyruk Birikmesi: Saniyede yüzlerce yeni istek gelmeye devam ederken hiçbir thread 15 saniye boyunca serbest kalmaz. Birkaç saniye içinde sunucudaki tüm bellek, soket ve thread havuzu tamamen dolar.
  3. Domino Etkisi (Cascading Failure): Artık o yavaş servisle hiçbir ilgisi olmayan "Profil Güncelleme", "Ürün Arama" veya "Ana Sayfa" istekleri bile boş thread bulamadığı için yanıt veremez hale gelir. Tek bir alt servisteki yavaşlık, tüm platformu domino taşı gibi devirmiştir.

Çözüm: Circuit Breaker (Devre Kesici) Mimarisi

Evlerimizdeki elektrik tesisatında yüksek akım geçtiğinde kablolar yanmasın diye sigorta (şalter) atar ve elektriği keser. Yazılım mimarisindeki Circuit Breaker deseni de birebir aynı mantıkla çalışır: Servis çağrılarını bir vekil (proxy) katmanıyla sarar ve hata/zaman aşımı oranlarını gerçek zamanlı izler.

Circuit Breaker bir durum makinesi (State Machine) olarak üç temel durumda çalışır:

1. Closed (Kapalı Durum — Normal Akış)

Elektrik devresinin kapalı olması gibi trafik normal şekilde hedef servise akar. Circuit Breaker bu sırada arka planda son N isteğin (veya son X saniyenin) başarı, hata (5xx) ve zaman aşımı (timeout) istatistiklerini tutar. Hata oranı belirlenen eşik değerin (örneğin %50) altında kaldığı sürece devre kapalı kalır.

2. Open (Açık Durum — Sigorta Attı / Fail-Fast)

Hata veya zaman aşımı oranı belirlenen eşiği aştığı anda şalter atar ve devre Open konumuna geçer.

  • Bu andan itibaren gelen hiçbir istek yavaş/çökmüş servise gönderilmez.
  • Sistem 15 saniye beklemek yerine 1 milisaniye içinde anında hata döner (Fail-Fast) veya bir Fallback (B Planı) devreye sokar.
  • Böylece ana sistemin CPU, RAM ve thread havuzu korunur; hem ana sistem ayakta kalır hem de boğulmakta olan alt servise nefes alma fırsatı verilir.

3. Half-Open (Yarı Açık Durum — Kontrollü İyileşme Testi)

Şalter sonsuza kadar açık kalmaz. Belirlenen bekleme süresi (resetTimeout, örneğin 30 saniye) dolduğunda devre Half-Open durumuna geçer.

  • Gelen trafiğin tamamı yerine yalnızca sınırlı sayıda test isteğinin (örneğin 3 istek) karşı servise geçmesine izin verilir.
  • Eğer bu test istekleri hızlı ve başarılı dönerse servis iyileşmiş demektir; şalter tekrar Closed konumuna geçer ve sistem kendi kendini iyileştirir (Self-Healing).
  • Test istekleri yine başarısız olursa şalter anında tekrar Open durumuna döner ve bekleme süresi yeniden başlar.

Kod Örneği: Minimal Circuit Breaker Mantığı

typescript
type State = "CLOSED" | "OPEN" | "HALF_OPEN";
 
class CircuitBreaker {
  private state: State = "CLOSED";
  private failures = 0;
  private nextAttempt = Date.now();
 
  constructor(
    private threshold = 5,
    private timeoutMs = 30_000
  ) {}
 
  async execute<T>(action: () => Promise<T>, fallback: () => T): Promise<T> {
    if (this.state === "OPEN") {
      if (Date.now() > this.nextAttempt) {
        this.state = "HALF_OPEN";
      } else {
        return fallback(); // Fail-fast & Fallback
      }
    }
 
    try {
      const result = await action();
      this.onSuccess();
      return result;
    } catch {
      this.onFailure();
      return fallback();
    }
  }
 
  private onSuccess() {
    this.failures = 0;
    this.state = "CLOSED";
  }
 
  private onFailure() {
    this.failures++;
    if (this.failures >= this.threshold || this.state === "HALF_OPEN") {
      this.state = "OPEN";
      this.nextAttempt = Date.now() + this.timeoutMs;
    }
  }
}

Graceful Degradation (Zarif Bozulma) ve Fallback Stratejileri

Circuit Breaker açıkken kullanıcıya her zaman kırmızı bir hata ekranı göstermek zorunda değilsiniz:

  • Öneri Servisi çöktüyse: Kullanıcıya kişiselleştirilmiş ürünler yerine Redis'te önbelleğe alınmış "En Çok Satanlar" listesini dönebilirsiniz.
  • Kargo Hesaplama Servisi yavaşladıysa: Sabit/tahmini bir kargo ücreti gösterip siparişi tamamlamasına izin verebilirsiniz.
  • Asenkron Kuyruklama: Kritik olmayan yazma işlemlerini Kafka veya RabbitMQ kuyruğuna atıp "İşleminiz alındı, arka planda tamamlanacak" yanıtı dönebilirsiniz.

Gerçek üretim ortamlarında bu yapıyı sıfırdan yazmak yerine Java ekosisteminde Resilience4j, .NET'te Polly, Node.js'te Opossum veya altyapı seviyesinde Envoy / Istio Service Mesh kullanarak doğrudan yapılandırabilirsiniz.

Bunu da oku