Resilience, Mikroservislerimizin meydana gelebilecek hataları tolere edebilme kabiliyetidir.
Mikroservislerimizde kısmı hatalar meydana gelebilir. Böyle hatalar meydana geldiğinde bunları tolere edebilmeliyiz.
Örn. 10 tane mikroservisimizin oluğunu ve bir tane mikroservisimizin 5 saniye boyunca down olduğunu düşünelim. Böyle bir senaryoda bir servisin down olması tüm sistemi etkilememeli ve mikroservis mimarimizin bunu tolere edebilmesi gerekir. Yada benzer şekilde bir mikroservimiz veri tabanına bağlanmak istediğinde veri tabanı 5 sn. cevap vermiyorsa bu 5 saniyelik gecikmeyi mikroservis mimarimizin tolere edebilme kabiliyeti olması gerekiyor.
Resilience Amacı : Kısmi bir hata meydana geldikten sonra uygulamanın çalışmasına aynen devam edebilmesidir.
Failure Example: Bu kısmi hatalara örnek olarak Network dar bağazı verilebilir.
Resilience Nasıl Arttırılabilir ?
- Retry
- Circuit Broker Pattern
- Microservisimizin resiliencysinin yüksek olmasını istiyorsak senkron ve asenkron iletişime dikkat etmemiz gerekiyor.
- Yukarıdaki örnekte Clientın ilk iletişime geçtiği microservisler E ve C mikroservisleridir. Client ile bu mikroservisler arası iletişim senkron olmalı mikroservislerimizin kendi aralarındaki ilişkiler ise asenkron olmalıdır.
Synchronous Communication : C Servisinden B servisine bir request attığımızda bu requestin sonucunu bekliyorsak ve bu süre zarfında bloklanıyorsak bu bir senkron iletişimdir. örn. REST, gRPC
Not: B Servisi down olursa bu request kaybolur.Dezavantaj
Asynchronous Communication : C Servisinden B Servisine data gönderiyorsak ve B sersinin bu data ile ne yaptığının sonucunu beklemiyorsak bu iki servis arasındaki iletişim asenkrondur. Bu tarz iletişimlerde C servisiden B servisine REST isteği yapmak yerine, bu isteği kuyruğa göndeririz. Bu isteği işleyecek olan servis yani B Servisi bu isteği kuyruktan alır ve kendi işlemlerini yapar. B Servisi belli bir süre down olsa bile istekler kuyrukta beklediği için kaybolmazlar. B Servisi tekrar ayağa kalktığında kuyrukta duran istekleri alır ve işlemlerini yapmaya devam eder.
Dikkat: Kullanıcıya bir data göstermek istiyorsak orada Asenkron iletişim olmaz. Yukarıdaki örnekte Client Catalogları listelemek istiyorsa C Servisine senkron bir istek atar. Client C servisinden bu requeste cevap dönene kadar bekler ve bu cevap içerisinde dönmüş olan dataları gösterir.
Poly Library: Microservislerimizde kısmi hataları handle etmeye imkan veren bir kütüphanedir.
Retry Pattern: Bir request başarısız olduğunda bu requestin kaybolup gitmesi yerine aynı işlemi ilgili birime tekrar göndermektir. E Servisi A servisine http ile bir istek atıyor olsun. A Servisinin kısa süreliğine down olduğunu ve tekrar ayağa kalktığını düşünürsek böyle bir senaryoda istek tekrar retry edilerek yani tekrar denenerek başarıyla ilgili servise ulaştırılır. Bu yöntemi isteği alacak servisin kısa süreli down olacağını düşündüğümüz senaryolarda kullanmalıyız.
TimeOut Pattern
Servisler arası http call yapıldığında bir servis timeouta düştüğünde requesti gönderen servisin çok fazla beklemesini önlemiş oluruz
Fallback
Call edilen servisin bir hata döndürmesi veya zaman aşımlarının meydana gelmesi durumunda döndürülebilecek değer veya gerçekleştirilebilecek eylem sağlamamıza olanak tanır.
Kaç kez yeniden denerseniz deneyin, başarısızlıkların olması kaçınılmazdır, bu nedenle başarısızlık durumunda ne yapılması gerektiğini planlamanız gerekir. Fallbackler genellikle retry, circuit breaker gibi politikalarla birlikte kullanılır.
BulkHead
Uygulamamızın herhangi bir bölümünün tüketebileceği toplam kaynak miktarını sınırlamamıza izin verir.
Order Servisi, Product deteylarını elde etmek için product servisini call ederse ve herhangi bir nedenle Product servisi kullanılamıyorsa, requestler order sevisinde yedeklenmeye başlar ve order servisininde performansının düşmesine ve hatta order servisinin çökmesine bile neden olabilir.
Bulkhead Isolation, uygulamanın bir bölümünü izole etmeye yardımcı olur ve Bellek, CPU, Soketler, thread vb. kullanımını kontrol eder, böylece uygulamanızın bir bölümü düzgün çalışmıyorsa, bu politika bu bölümün tüm uygulamayı etkilemesini veya durdurmasını engeller.
Circuit Breaker Patern:
Başarısız http request sayısı daha önceden belirlediğimiz hata sayısı değerini aştığında belirlediğimiz süre boyunca request atılan servise istek atılmasını önlemiş olacağız.
E Servisi A servisine 3 saat gibi bir süre boyunca erişemezse gereksiz yere retry pattern ile E Servisinden A Servisine istek atıyor oluruz. Down olan bir servisin 3 saniye yada 5 saniye gibi kısa bir sürede ayağa kalkacağını düşünüyorsak retry patterni uzun bir süre down olarak kalacağını düşünüyorsak circuit breaker pattern kullanmalıyız.
A ve B olmak üzere 2 adet servisimiz ve Open, Close ve Half Open olmak üzere 3 adet durumumuz var.
Closed Devre Durumu: A Servisi B Servisine istek atabiliyor. Bizim kuralımıza göre A Servisi B Servisine 30 saniye boyunca 5 adet başarısız istek atarsa devre Open Statuye geçsin.
Open Devre Durumu: Devrenin statusu Open ise A Servisi B Servisine istek attığında Circuit Breaker Pattern araya giriyor ve B Servisine istek atmak yerine direkt Exception dönüyor. B Servisinin ayakta olmadığını bildiği için gereksiz yere istek göndermiyor. İkinci kuralımız ise 60 saniye bekle ve durumu Half Open Statuye geçir.
Half Open Devre Durumu: Half Open Statudeyken A Servisi B Servisine bir adet istek atıyor. Eğer B Servisi ayaktaysa sistem Close Devre Durumuna geçiyor ve düzgün şekilde işlemeye devam ediyor. Fakat B Ayakta değilse tekrar Open Devre Durumuna geçip Exception fırlatmaya devam ediyor.
Github Uygulama
BLOG REFERENCE