Erhan Ballıeker

Resilient Network Services Bölüm 6 – Polly – 3 (Circuit Breaker, Advanced Circuit Breaker, Fallback Policies)

Selamlar,

Bu seri kapsamında en güçlü kütüphane olduğunu düşündüğüm Polly nin detayalrına devam ediyor olacağım. Önceki yazımda Retry,ForeverRetry, Wait and Retry gibi kullanışlı senaryoları detaylı bir şekilde kullanımını kapsayan örneklerine değinmiştim. Bu yazımda Fallback ler ve Circuit Breaker senaryolarını Polly ile nasıl uygulayabileceğimize değinmek istiyorum.

 

Circuit Breaker

Belli bir tipte hataların sıklaşması kendini yinelemesi gibi durumlarda, sistemin sürkli hataları responselar almaya başladığı durumlarda, daha fazla zaman kayına uğratmadan uygulamamızı kısıtlamalar yapabilmemiz mümkün.  Adından da az çok anlaşılacağı üzere bu pattern zaten, bir hatalı request-response lar loop una girilmiş senaryoda müdahil olup, fail-fast-move-on(” yani çok takılma olut bunlar sen işine bak 🙂 “) yaklaşımı ile duruma el atmamızı sağlıyor.

// Belli bir exception tipinden hatayı söylediğimiz sayıdan fazlaca
// aldığımız durumlarda bu loop u kesmek için
// belli bir bekleme süresi verip circuit-break ettiğimiz yani bu loop u 
// kestiğimiz durum
Policy
    .Handle<SomeExceptionType>()
    .CircuitBreaker(2, TimeSpan.FromMinutes(1));

// Belli tipten bir hatayı belli bir sayıda aldığımız da
// circuit breake i uygulayacağımız süreyi söyleyip, circuit in state inin
// değiştiği durumlarda yapmak istediğimiz aksiyonları söylediğimiz durum
Action<Exception, TimeSpan> onBreak = (exception, timespan) => { ... };
Action onReset = () => { ... };
CircuitBreakerPolicy breaker = Policy
    .Handle<SomeExceptionType>()
    .CircuitBreaker(2, TimeSpan.FromMinutes(1), onBreak, onReset);

// Belli tipten bir hatayı belli bir sayıda aldığımız da
// circuit breake i uygulayacağımız süreyi söyleyip, circuit in state inin
// değiştiği durumlarda yapmak istediğimiz aksiyonları 
// ilgili Context i de belirtip kullanarak söylediğimiz durum
Action<Exception, TimeSpan, Context> onBreak = (exception, timespan, context) => { ... };
Action<Context> onReset = context => { ... };
CircuitBreakerPolicy breaker = Policy
    .Handle<SomeExceptionType>()
    .CircuitBreaker(2, TimeSpan.FromMinutes(1), onBreak, onReset);

// Circuit state ini incelemek istediğimiz durumlarda CircuitState porpertysi
// ile buna ulaşabiliriz. Mesela HEalthMobitoring için vb gibi.

CircuitState state = breaker.CircuitState;

/*
CircuitState.Closed - Normal işlem. Verdiğimiz action lar bu state de iken çalışabilir.

CircuitState.Open - Verdiğimiz bekleme süresinin dolduğu ve circuit in yeniden açıldığı durum. Verdiğimiz action lar bu state de çalışamaz.

CircuitState.HalfOpen - Bekleme süresi dolduğunda yeniden open state geçmeden önceki süreç, bu sırada actionlar çalışabilir ve
state in birsonraki durumda da open mı yoksa closed mu olacaklarına karar verebilirler.

CircuitState.Isolated - Manuel olarak Circuit ın state ini açık tuttuğumuz durum. Action lar bu state de çalışamaz.
*/

// Manuel olarak İlgili circuit ın state ini open tutup çalıştırabiliriz.
breaker.Isolate(); 
// brekaer ı reset edip closed state e manuel olarak alabiliriz. Bu durumda verdiğimiz 
actionların çalışmasının tetiklenmesini sağlamış oluruz
breaker.Reset(); 

Circuit Open State de iken;

  • Verdiğimiz herhangi bir Action delegate çalışmaz
  • BrokenCircuitException tipi ile call direk fail olur ve bu fail içerisinde fail olmasının sebebi olan son hata gösterilir (Inner exception olarak)

Aşağıda ki şekilde Circuit Breaker nasıl çalıştığını ve state ler arasındaki geçişin nasıl olduğuna bakalım.

c4136890-17cb-11e6-9ffb-3777dd102962

Circuit hayatına ilk olarak Closed state ile başlar. Circuit close olduğunda,

  • circuit-breaker verdiğimiz action delegate leri çalıştırır ve bu actionların başarılı sonuçlanmasını ve hata almalarını gözlemler.
  • Eğer alınan hataların sayısı verdiğimiz değere ulaşırsa, circuit-breaker state OPEN duruma geçer, tüm exceptionları throw eder.
  • Open state de iken action delegate ler çalışmazlar. Yukarıda söylediğimiz gibi circuit-breaker BrokenCircuitException ile hata fırlatır ve break olmasının sebebi olan son hata da InnerException olarak verilir.
  • Verilen süre boyunca circuit-breaker OPEN state de bekler. Sonrasında HALF_OPEN state e geçer.
  • Bu durumda iken verilen sıradaki action delegate çalışır. Eğer bu action herhangi bir handle edilmiş exception yakalar ise circuit-breaker ın state direk olarak OPEN a geri döner. Eğer hata almadan çalışırsa state CLOSE a döner.

Buradaki ters çalışma mantığı kafa karıştırmasın. Bir elektrik devresi gibi düşünün. Circuit CLOSED state de iken herşey yolunda işler çalışıyor demektir. OPEN state e geçtiğinde ise iş akışı durmuş hata fırlatılmış ve circuit bekletiliyor demektir.

 

Advanced Circuit Breaker

Polly nin klasik Circuit Breaker ının yetmediği durumlarda AdvancedCircuitBreaker adında daha detaylıca circuit oluşturmanızı sağlayan bir metodu var. Bu metod sayesinde belli bir hata sayısı yerine çalışan action delegate ler içindeki hata oranını, belli bir süre içinde çalışması gereken minimum action sayısını vs vererek, daha dinamik parametrelerle daha ince hazırlanmış bir circuit oluturabilirsiniz.



Policy
    .Handle<SomeExceptionType>()
    .AdvancedCircuitBreaker(
        failureThreshold: 0.5, 
        samplingDuration: TimeSpan.FromSeconds(10),
        minimumThroughput: 8,          
        durationOfBreak: TimeSpan.FromSeconds(30)                 
);

Circuit breker ın kullanıldığı yerleri ve kullanım şekilleri detayları için aşağıdaki yazıları da okumanızı öneririm.

 

Fallback

Bir hata yakalanması işlemi durumunda hata yerine default bir değer dönmek için kullanacağınız yöntem. Örneğin bir ilan resmi yüklemek adına bir request atıldı, hata alındığında bunun yerine default bir imaj basmak senaryosu gibi.

// Gerçek değer alınamadığında default bir değer dönmek için
Policy
   .Handle<Exception>()
   .Fallback<UserAvatar>(UserAvatar.Blank)

// Default değeri dönerken bir func çalıştırmak istediğimiz de kullanacağımız yöntem
Policy
   .Handle<Exception>()
   .Fallback<UserAvatar>(() => UserAvatar.GetRandomAvatar()) // where: public UserAvatar GetRandomAvatar() { ... }

// hem bir değer dönmek hemde hata olduğuna dair bir action çalışıtırmak istediğimiz zaman kullanacağımız yöntem.
Policy
   .Handle<Exception>()
   .Fallback<UserAvatar>(UserAvatar.Blank, onFallback: (exception, context) => 
    {
        // do something
    });

Polly nin Circuit Breaker patterni nin uygulanması ile ilgili bize neler sağladığını ve Fallback senaryolarında yapabileceklerimizi özetle görmüş olduk.

Bir sonraki yazımda son olarak Polly nin Bulkhead, Cache, COnfiguration ve Policy Execution ile ilgili kısımlarına değinip artık tüm bu kütüphaneleri bir xamarin projesinde nasıl kullanırız buna bakmak istiyorum.

Bir sonraki yazımda görüşmek üzere.

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Connecting to %s

%d blogcu bunu beğendi: