Circuit Breaker Pattern Nedir?

Gökhan Ayrancıoğlu
5 min readFeb 11, 2021

--

Circuit Breaker Pattern, bir yazılımda hataları tespit ederek hatanın tekrar etmemesini sağlar. Böylece sistemde hataların tekrar etmesi sonucu oluşacak bloklanma, hizmet kesintileri, aşırı kaynak kullanımı gibi sorunlarla karşılaşılmasını önleyerek, sistemin sağlıklı çalışmasını amaçlar.

Yazılım sistemlerinde farklı servis veya sistemlere istekte bulunmak/çağrı yapmak oldukça sık kullandığımız bir yöntemdir. Microservice mimarisindeki servisler arası senkron iletişim de buna dahil edilebilir. Özellikle çoğu kurumsal yazılım sisteminde Saas, CRM, SAP gibi birçok sisteme entegre olma çoğu yazılımın kaderi haline geliyor. Böyle bir yapıda hizmet aldığımız servis ya da sistem üzerinde oluşabilecek farklı sorunlarla karşı karşıya kalabiliyoruz.

  • Oluşturulan isteklerin başarısız olması,
  • İstek atılan servis ya da sistemin ayakta olmaması
  • İstek atılan servisin geç cevap vermesi/timeout durumuna düşmesi

gibi durumlarda sorunların arka arkaya tekrar etmesi daha büyük sorunlara yol açmaktadır. İstekte bulunulduğunda yanıt vermeyen bir servis çok sayıda çağrının birikmesi sonucu yığılmaya dolayısıyla threadlerin bloklanmasına, aşırı kaynak tüketimine ve bütün bunların sonucunda servisinizin yanıt veremez konuma gelmesine yani hizmet kesintilerine neden olabilir. Böyle bir durumda istek atılan servis düzelse bile servisinizdeki kitlenme büyük ölçüde yazılımınızın tümünde arızalara veya sistem aksaklıklarına neden olabilir.

Hikaye: Elektrik mühendisliğinde circuit breaker(devre kesici) yapıları hali hazırda fazlaca kullanılıyor. Circuit Breaker: bir elektrik devresini oluşabilecek olumsuz bir duruma karşın hasardan korumak için elektrik akışını kesen otomatik elektrik anahtarlarıdır. Yazılım geliştirmede, uygulamanızı koruyan çok benzer bir işi yapan circuit breaker pattern’nine sahibiz.

Sorun Örneklemi

Bir ödeme sistemi geliştirdiğinizi düşünün. Böyle bir sistemde onlarca banka ile entegrasyon mevcuttur. Dolayısıyla kullanıcıların işlemlerini tamamlayabilmek için bankaların API’larını kullanarak güvenli bir ödeme altyapısı sunabiliriz. Dolayısıyla her bir ödeme ya da iade işlemi bu bankaların API’ları aracılığıyla gerçekleşir. Bu işlemleri gerçekleştirmek için bankaların API’larını kullanırız ve bankadan daha güvenilir bir sistem olabilir mi diye hayal edip rahatça hayatımıza devam edebiliriz.

Ancak olumsuz bir senaryoyla da karşılaşabiliriz. API’ını kullandığınız bir banka yanıt vermiyor ve API’larına gelen tüm istekler belirli bir zaman sonra zaman aşımına uğruyor. Threadler bloklanıyor ve sisteminiz yanıt veremez hale geliyor. Herhangi bir sorunda beş-on dakikalık kesintiler bile sizin belki de milyarlarca lira kaybetmenize neden olabilir.

Çözüm: Circuit Breaker Pattern

Genel olarak Circuit Breaker, hizmet alınan(istek atılan) bir servisin kullanılabilirliğini kontrol edip oluşabilecek hatalarda sistemimizi belirttiğimiz türdeki sorunlardan korumak için kullanılabilir. Hizmet alınan yapı bir servis, bir veritabanı sunucusu veya uygulama tarafından kullanılan bir web hizmeti olabilir. Circuit breaker, hataları algılar ve uygulamanın başarısız işlem sayısı belirli bir eşiği geçmesi durumunda ise yeniden kullanılabilir hale gelene kadar işlemleri engeller.

Uzak/diğer servislere isteği gerçekleştiren fonksiyon bir circuit breaker yapısı içerir. Bir servis oluşturduğu isteği oluşabilecek hata ve sorunlara karşın circuit breaker’ı proxy gibi kullanarak işlemini gerçekleştirir. Hataların oluşması durumunda circuit breaker’ın devreye girmesi için belirlenen eşik değeri aşıldığında circuit breaker açılır ve alarm durumuna geçer. Belirli bir eşik süre boyunca da üzerinden geçen istekleri işleme koymadan başarısız sayar. Belirlenen bir süre sonra karşıdaki sistemin durumunu kontrol etmek için circuit breaker yarı açık konuma geçer ve belirli bir eşikte isteğin gönderilmesine izin verilir. İşlemler eğer başarılı gerçekleşirse sistem işleyişi normal hayatına devam eder, aksi takdirde işlemler yeniden başarısız sayılır ve circuit breaker açık konuma gelir. Böylece bu döngü tekrar ettirilebilir. Başarısız istekler için yine alternatif çözüm yöntemleri mevcutsa o işlemleri gerçekleştirebilir.

Circuit Breaker Durumları

Closed(Kapalı): Circuit breaker’ın başlangıç konumu kapalıdır. Her şeyin beklendiği gibi çalıştığı ve tüm istek akışının olağan şekilde devam ettiği durumdur. İstek atılmak istenilen servise ulaşılırken herhangi bir hata alınıyorsa ve bu hatalar eşik kriterlerini aşıyorsa circuit breaker devreye girer.

Open(Açık): Açık durum, herhangi bir işlemin tamamlanmasına izin vermeden başarısız işlem olduğunu varsayar. Zaman aşımı ya da hatalı işlemler buna yol açmış olabilir. Tüm istekleri göndermeye çalışmadan belirli bir süre için reddeder ya da alternatif yöntem belirlendiyse ona yönlendirebilir. Her halükarda işlemin zaman kaybetmesi veya sistemde başka sorunlara yol açması engellenir.

Half-Open (Yarı Açık): Circuit Breaker istek atılan servisin durumunu test etmek için açık durumdayken belirli bir eşiğe ulaşıldıktan sonra durum yarı açık konuma geçer ve sınırlı sayıda ya da sürede isteğin atılmasına izin verir. Bu yarı açık durumda eşik değerinin üstünde hata alınırsa circuit breaker bir kez daha açık duruma geçer ve bu döngü devam edebilir. Bazen yarı açık konumda tek bir hata ile karşılaşılsa dahi sistem circuit brekar’ın açık konumuna gelebiliyor. Hata gözlenmezse circuit breaker kapalı konuma getirilerek sistemin olağan işleyişine izin verilir.

Bütün bu durum değişiklikleri, belirli bir zaman dilimindeki hata oranları, gecikme, trafik ve hatta kaynak kullanımı gibi kriterleri içerebilen, eşik kriteri/değeri(threshold) olarak bilinen önceden belirlenmiş kriterlere bağlıdır.

Örnek senaryomuzda yarı açık konumda farklı bankalara yönlendirme yapılarak sistemin olağan işlemlerine devam etmesi de sağlanabilir. Circuit breaker’ın açık olduğu konumda hata dönmeden alternatif yöntemlerle(eğer mevcutsa) çözümlemekte oldukça sık kullanılan bir yöntemdir.

Doğru Eşik Kriterlerinin Belirlenmesi

Eşik değeri diye bahsettiğimiz kriter aslında sadece istek sayısından oluşan bir kavram değildir. Circuit breaker pattern’i için kullanılabilecek bazı yaygın eşikler sunucu zaman aşımı(timeout), hata sayısı, beklenmeyen response kodları veya aşırı kaynak tüketimi olabilir. Örneğin, kullanıcı bilgileri üzerinden işlem yapan bir servis için işlem süresi daha önemliyken, ödeme sistemiyle ilgili bir serviste ise hata sayısı eşik kriterlerinden en önemlisi olabilir.

Hata durumlarında yapılabilecekler

Circuit Breaker ile birlikte istek atarken oluşan hata durumlarının sonucunda gereksiz istekleri önleyebiliriz. Bu pattern ile hata durumlarında yapılacak işlemler sistemin sağlıklı işleyişi için önemli bir rol oynar.

  • Bazı istekler başarısız olduğunda bunları alternatif API’lar kullanarak istekleri yönlendirilebilir ve işlemlerdeki aksaklıkların önüne geçilebilir.
  • Oluşan hata durumunda Generic API’lar için cache mekanizması kullanılabilir ve hata durumunda cache üzerinden okunarak cevap dönülebilir.
  • Kullanıcıya işlemin devam ettiğine dair kullanıcı bilgilendirilebilir ve arka planda işlem yeniden denenebilir.

— Bana ulaşmak için: Twitter, Linkedin

— Kodlar konuşsun: Github

— 1:1 görüşmeler için: Superpeer

https://gokhana.dev

Bazı dillerdeki kütüphaneler;

Hystrix -Java
circuit_breaker or simple_circuit -Ruby
go-circuitbreaker -Go
circuitbreaker -Python
failsafe -Rust

Kaynakça

--

--

Gökhan Ayrancıoğlu

Software Engineer @Yemeksepeti • #Java • #Spring Boot • #Kotlin • #Spark • #Microservices • https://gokhana.dev