Dayanıklılık Desenleri: Circuit Breaker, Bulkhead, Timeout

Yüksek trafikte dayanıklılık: circuit breaker durumları, bulkhead izolasyonu, timeout bütçeleri, retry fırtınalarından korunma ve kademeli çöküşün (cascading failure) anatomisi.

Circuit breaker ve bulkhead yapılandırmasını gösteren kod editörü penceresi

Kademeli çöküş (cascading failure) nasıl başlar?

Hep aynı senaryoyla: bir bağımlılık yavaşlar — çökmez, yavaşlar. Onu bekleyen thread'ler birikir, havuzlar dolar, bekleyenleri bekleyenler birikir ve beş dakika içinde sağlam servisler de cevap veremez olur. Dayanıklılık desenlerinin tamamı tek bir hedefe çalışır: bir bileşenin arızasını o bileşenin sınırında durdurmak. Bu yazı dört temel deseni ve birlikte çalışma düzenlerini kurar.

Desen haritası

Desen

Durdurduğu şey

Anahtar parametre

Timeout

Sonsuz bekleme

Uçtan uca gecikme bütçesinin payı

Retry (backoff+jitter)

Geçici hataların kullanıcıya yansıması

Deneme sayısı + retry bütçesi

Circuit breaker

Ölü bağımlılığı dövmek

Hata eşiği, açık kalma süresi

Bulkhead

Bir bağımlılığın tüm kaynakları tüketmesi

Bağımlılık başına havuz/izin sınırı

Timeout: her çağrının vadesi vardır

Timeout'suz uzak çağrı, süresiz rehin verilmiş thread'dir. İki disiplin: birincisi, her dış çağrıda (HTTP, veritabanı, kuyruk, önbellek) açık timeout — kütüphane varsayılanlarına güvenilmez, çoğu 'sonsuz'dur. İkincisi, timeout'ların bütçe olarak tasarlanması: kullanıcıya 2 saniyede cevap sözü varsa, zincirdeki servislerin timeout'ları toplamda bu bütçeye sığmalıdır — A servisi 1,5sn bekleyip B'ye 1,5sn timeout verirse bütçe daha ilk halkada aşılmıştır. Bütçe, çağrı zinciri boyunca kalan süre olarak taşınır; kalan süre yetmeyecekse çağrı hiç yapılmaz, hızlı hata dönülür.

Retry: ilaç ve doz

Retry geçici hataları (ağ kesintisi, anlık yoğunluk) kullanıcıdan gizler; dozunda alınmazsa yükü katlayan zehirdir. Kurallar nettir: yalnızca idempotent ve geçici hata sınıflarında retry (bağlantı hatası evet, 400 asla, timeout ise 'işlem gerçekleşmiş olabilir' bilinciyle); exponential backoff + jitter (senkronize retry dalgalarını kırmak için); retry bütçesi (toplam trafiğin küçük bir yüzdesi — hata oranı yükselince retry'ın kendisi kısılır); ve zincirde tek katman retry yapar — her katman kendi başına denerse üç katmanlı zincirde bir hata 27 çağrıya patlar.

Circuit breaker: ölüyü dövmeyi bırakmak

Bağımlılık gerçekten hastaysa retry çare değil işkencedir. Devre kesici üç durumlu bir makinedir: Kapalı (normal akış; hata oranı izlenir) → eşik aşılınca Açık (çağrılar hiç yapılmaz, anında fallback döner; hasta sisteme nefes alanı) → süre dolunca Yarı-Açık (sınırlı deneme trafiği; başarılıysa Kapalı'ya, değilse Açık'a döner). İki mühendislik inceliği: eşikler istek hacmine duyarlı olmalı (10 istekte 5 hata ile 10.000 istekte 5.000 hata aynı oran, farklı anlam) ve breaker durumu panoda görünmelidir — 'hangi devreler açık?' sorusu, olay anında ilk bakılan ekrandır. Fallback tasarımı da breaker kadar önemlidir: önbellekten bayat veri, varsayılan cevap veya özelliğin zarifçe gizlenmesi — boş ekran fallback değildir.

Bulkhead: gemiyi bölmelere ayırmak

Adını gemi perdelerinden alan desen, kaynak izolasyonudur: her dış bağımlılığa ayrı havuz/eşzamanlılık sınırı tanınır — ödeme servisi çağrıları en fazla 50 eşzamanlı izin kullanır, öneri servisi 20. Öneri servisi yavaşladığında yalnızca kendi 20 iznini tüketir; ödeme yoluna dokunamaz. Sanal thread çağında havuzun yerini semaphore bazlı izin sınırları alır ama ilke değişmez: paylaşılan kaynak, paylaşılan kader demektir — izole edilmemiş her bağımlılık, en kritik akışınızın gizli ortağıdır. Kritik/kritik-olmayan ayrımı burada da geçerlidir: sipariş yolu ile raporlama aynı bağlantı havuzunu paylaşmamalıdır.

Desenlerin orkestrasyonu: sıralama ve sahiplik

Dört desen iç içe çalışır ve sıralaması önemlidir: dıştan içe bulkhead (izin var mı?) → circuit breaker (devre kapalı mı?) → timeout (bütçe yeter mi?) → çağrı → hata sınıfına göre retry kararı. Resilience4j gibi kütüphaneler bu zinciri bildirimsel kurar; kritik olan yapılandırmanın bağımlılık başına bilinçli yazılmasıdır — tüm servislere aynı kopyala-yapıştır değerler, dayanıklılık değil dekordur. Her bağımlılığın SLA'sı, hata karakteri ve iş kritikliği farklıdır; parametreler bu gerçeklikten türetilir ve chaos/yük testleriyle doğrulanır.

İş etkisi: arıza yerelken olay, yayılınca kriz olur

Dayanıklılık desenlerinin ticari karşılığı, arıza yarıçapının küçülmesidir: öneri servisi çöktüğünde öneriler kaybolur — satış devam eder; ödeme sağlayıcısı yavaşladığında ödeme kuyruğa alınır — site ayakta kalır. Bu fark, olay raporlarında 'kısmi hizmet etkisi' ile 'tam kesinti' arasındaki farktır ve SLA cezaları, kayıp ciro, itibar üçgeninde doğrudan paraya çevrilir. Desenler kurulduktan sonra tatbikatsız bırakılmamalıdır: bağımlılık arızası simülasyonları (chaos testleri), fallback'lerin gerçekten çalıştığının tek kanıtıdır.

Sık sorulan sorular

Circuit breaker her dış çağrıya mı kurulmalı?

Ağ üzerinden giden ve arızalanabilen her önemli bağımlılığa — evet. Maliyeti düşük, kazancı arıza anında büyüktür; ama parametreleri bağımlılığa özgü ayarlanmalıdır.

Timeout değerini nasıl seçerim?

Bağımlılığın gerçek gecikme dağılımından (p99 + pay) ve uçtan uca bütçeden geriye doğru. Sabit 30 saniye varsayılanı, pratikte 'timeout yok' demektir.

Retry ile idempotency ilişkisi ne?

Retry ancak tekrarı güvenli işlemlerde meşrudur. Yazma işlemlerinde idempotency anahtarı yoksa, timeout sonrası retry çift etki (çift sipariş, çift tahsilat) riskidir.

Bu desenler monolitte de gerekli mi?

Evet — monolit de veritabanına, ödeme sağlayıcısına, e-posta ve arama servislerine dış çağrı yapar. Kademeli çöküş mikroservis tekeli değildir.

Dayanıklılık kontrol listesi

  1. Her dış çağrıda açık timeout; uçtan uca gecikme bütçesi tanımlı

  2. Retry yalnızca idempotent+geçici sınıfta; backoff+jitter+bütçe kurulu

  3. Zincirde retry tek katmanda; katmanlar arası çarpan yok

  4. Kritik bağımlılıklarda circuit breaker + anlamlı fallback

  5. Bağımlılık başına bulkhead/izin sınırı; kritik yollar izole

  6. Breaker durumları ve bağımlılık sağlığı panoda

  7. Chaos/arıza tatbikatları düzenli; fallback'ler kanıtlı

SSH Yazılım, dayanıklılık desenlerinin tasarımını ve Resilience4j tabanlı kurulumunu uçtan uca gerçekleştirir. Arıza yarıçapınızı birlikte küçültelim.