Bayramlar bitdi və biz Istio Service Mesh seriyamızın ikinci yazısı ilə geri döndük.

Bu günün mövzusu – Circuit Breaker, yəni azərbaycanca «avtomatik qırıcı», dilimizdə isə «müdafiə avtomatı» kimi tanınır. Ancaq Istio’da bu avtomat, qısa dövrəyə və ya yüklənmiş dövrəyə deyil, səhv olan konteynerləri söndürür.
İdeal olaraq necə işləməlidir
Mikroservislər Kubernetes tərəfindən idarə olunduqda, məsələn, OpenShift platformasında, yükə əsasən avtomatik olaraq yuxarı və aşağı miqyaslanır. Mikroservislər pod'larda işlədiyi üçün, bir son nöqtədə eyni konteynerləşdirilmiş mikroservisdən bir neçə nüsxə ola bilər və Kubernetes sorğuları yönləndirəcək və onların arasında yük balansı təmin edəcək. İdeal olaraq, bütün bunlar mükəmməl işləməlidir.
Biz unutmamalıyıq ki, mikroservislər – kiçik və efemeridir. Buradakı efemerlik, yaranma və yox olmanın asanlığını bildirir, bu isə çox zaman qiymətləndirilmir. Bir mikroservisin pod'da yaranma və ölüm prosesi gözləniləndir, OpenShift və Kubernetes bunun öhdəsindən mükəmməl gəlir, və hər şey ideal olaraq işləyir – amma yenə də yalnız nəzəriyyədə.
Gerçəkdə bu necə işləyir
İndi təsəvvür edin ki, müəyyən bir mikroservis nüsxəsi, yəni konteyner, işləmir: ya cavab vermir (503 xətası) ya da – daha pisi – reaksiya verir, amma çox yavaş. Yəni, o, bir az prosesi pozur və ya sorğulara cavab vermir, amma resurslardan avtomatik olaraq çıxarılmır. Bu halda nə etmək lazımdır? Yenidən cəhd etmək? Onu marşrutlaşdırma sxemindən çıxarmaq? Və «çox yavaş» nəyə bərabərdir – bu ədədlər nədir və kim onları müəyyən edir? Bəlkə, ona bir az vaxt vermək və daha sonra cəhd etmək lazımdır? Əgər belədirsə, nə qədər sonra?
Istio'da Pool Ejection nədir
Burada Istio, səhv olan konteynerləri marşrutlaşdırma və yük balansı resurslarından müvəqqəti olaraq çıxaran Circuit Breaker müdafiə avtomatları ilə kömək edir və Pool Ejection prosedurunu həyata keçirir.
Istio, anomaliyaların aşkar edilməsi strategiyası (outlier detection) istifadə edərək, ümumi sıradan çıxan qırıq pod'ları aşkar edir və onları müəyyən bir vaxt, «yuxu pəncərəsi» (sleep window) adlandırılan vaxt ərzində resurslar dəstəsindən çıxarır.
Bunun Kubernetes-də OpenShift platformasında necə işlədiyini göstərmək üçün, repositoriyadakı nümunədən normal işləyən mikroservislərin ekran görüntüsü ilə başlayaq. . Burada bizdə v1 və v2 adlı iki pod var, hər birində bir konteyner işləyir. Istio marşrutlaşma qaydaları istifadə edilmədikdə, Kubernetes standart olaraq uyğun şəkildə balanslaşdırılmış dövrü marşrutlaşma tətbiq edir:

Fasiləyə hazırlaşaq
Pool Ejection etmədən əvvəl Istio yönləndirmə qaydası yaratmaq lazımdır. Tutaq ki, pod’lar arasında sorğuları 50/50 nisbətində yaymaq istəyirik. Bundan əlavə, v2 konteynerlərinin sayını bir ədəddən iki ədədə qaldıracağıq, beləliklə:
oc scale deployment recommendation-v2 --replicas=2 -n tutorial
İndi tıxacların 50/50 nisbətində pod’lar arasında yayılmasını təmin edən yönləndirmə qaydasını təyin edirik.

Qaydaların işləməsinin nəticəsi belə görünür:

Bu ekranda 50/50 deyil, 14:9 olduğunu irad tutmaq olar, amma zamanla vəziyyət düzələcək.
Fəlakət yaradırıq
İndi iki v2 konteynerindən birini sıradan çıxaracağıq ki, bir mühərrik v1, bir mühərrik v2 və bir sıradan çıxmış mühərrik v2 olsun:

Fəlakəti düzəldirik
Beləliklə, bir sıradan çıxmış konteynerimiz var və Pool Ejection vaxtıdır. Çox sadə bir konfiqurasiya vasitəsilə bu sıradan çıxmış konteyneri 15 saniyə ərzində bütün yönləndirmə sxemlərindən istisna edəcəyik, beləliklə, onun öz-özünə düzəlməsi(ya yenidən başlatılması, ya da iş qabiliyyətini bərpa etməsi) gözlənilir. Bu konfiqurasiya və onun fəaliyyətinin nəticələri belə görünür:


Göründüyü kimi, sıradan çıxmış v2 konteyneri artıq sorğuların yönləndirilməsində istifadə edilmir, çünki o, puldan çıxarılıb. Amma 15 saniyə sonra avtomatik olaraq yenidən pula qayıdacaq. Beləliklə, biz yalnız Pool Ejection’ın necə işlədiyini göstərdik.
Memarlığı qurmağa başlayırıq
Pool Ejection, Istio-nun monitorinq imkanları ilə birləşərək, uğursuz konteynerlərin avtomatik əvəzlənməsi çərçivəsini yaratmağa imkan verir ki, bununla da dayanma müddətini azaltmağı və ya tamamilə aradan qaldırmağı mümkün etsin.
NASA-nın bir məşhur devizi var - Failure Is Not an Option, bunu uçuş rəhbəri yazdığı bildirilir . Rus dilinə "Uğursuzluq variant deyil" kimi tərcümə olunur və burada vurğulanır ki, hər şey kifayət qədər iradə ilə işlədilə bilər. Lakin gerçək həyatda uğursuzluqlar yalnız baş vermir, onlar qaçılmazdır, hər yerdə və hər şeydə olur. Mikrosistemlərdə onlarla necə mübarizə aparmalıyıq? Bizim fikrimizcə, iradəyə güvənmək yaxşı deyil, konteynerlərin imkanlarına güvənmək daha yaxşıdır. , ilə imzalanmalıdır, .
Yuxarıda da qeyd etdiyimiz kimi, Istio, fizik aləmdə yaxşı tanınan avtomatik çəngəllərin konsepsiyasını həyata keçirir. Elektrik çəngəli problemin olduğu zəncir hissəsini dayandırarkən, proqram çəngəli (Circuit Breaker) Istio-da, istinad nöqtəsi ilə bir şey düzgün olmadıqda, məsələn, server sıradan çıxdıqda və ya yavaşladıqda, sorğu axını ilə sıradan çıxmış konteyner arasındakı əlaqəni kəsir.
İkincisi, daha fazla sorun yaratır, çünkü bir konteynerin duraklaması, ona başvuran hizmetlerde zincirleme gecikmelere neden olur ve sonuç olarak sistemin genel performansını düşürür. Ayrıca, zaten yavaş çalışan hizmete tekrar eden istekler doğurur ki bu durumu daha da kötüleştirir.
Circuit Breaker'ın teorisi
Circuit Breaker, isteklere yönelik akışı kontrol eden bir proxy'dir. Bu son nokta çalışmayı durdurduğunda veya ayarlarına bağlı olarak yavaşlamaya başladığında, proxy konteynerle bağlantıyı keser. Trafik, yük dengelemesi nedeniyle diğer konteynerlere yönlendirilir. Bağlantı, belirlenmiş bir uyku penceresi süresince açık (open) kalır, örneğin iki dakika, ardından yarı açık (half-open) olarak kabul edilir. Bir sonraki isteği göndermeye çalışmak, bağlantının gelecekteki durumunu belirler. Hizmetle ilgili bir sorun yoksa, bağlantı tekrar çalışır hale gelir ve kapanır (closed). Ama sorun devam ederse, bağlantı yeniden açılır ve uyku penceresi yeniden başlatılır. İşte Circuit Breaker'ın durum değişikliklerinin basitleştirilmiş bir diyagramı:

Burada önemli olan, tüm bunların sistem mimarisi seviyesinde gerçekleştiğidir. Bu nedenle, bir noktada uygulamalarınızı Circuit Breaker ile çalışmaya öğretmek zorunda kalacaksınız; örneğin, varsayılan bir değer sunmak veya mümkünse hizmetin varlığını göz ardı etmek. Bunun için bulkhead pattern kullanılır, ancak bu yazının kapsamını aşar.
Circuit Breaker'ın uygulamada
Örneğin, OpenShift'te tavsiye mikroservisimizin iki versiyonunu başlatacağız. Versiyon 1 normal çalışacak, ancak v2'ye bir gecikme ekleyeceğiz, böylece sunucudaki duraklamaları taklit edebileceğiz. Sonuçları görmek için şu aracı kullanıyoruz: :
siege -r 2 -c 20 -v customer-tutorial.$(minishift ip).nip.io

Her şey yolunda gibi görünüyor, ama ne pahasına? İlk bakışta 0 erişilebilirlik varmış gibi gözüküyor, ama dikkat edin - en uzun işlem süresi tam 12 saniye. Bu belirgin bir darboğaz ve açılması gerekiyor.
Bunu yapmak için, Istio ile yavaş konteynerlere yapılan çağrıları hariç tutacağız. İşte Circuit Breaker kullanımında ilgili yapılandırmanın nasıl göründüğü:

Son satırdaki httpMaxRequestsPerConnection parametresi, mevcut olan ek bir bağlantı oluşturmaya çalışıldığında bağlantının kesilmesi gerektiğini belirtir. Bizim konteynerimiz duraklatan bir hizmeti taklit ettiğinden, bu tür durumlar periyodik olarak ortaya çıkacak ve o zaman Istio 503 hatası döndürecektir. İşte siege'ın gösterecekleri:

Tamam, elimizde Circuit Breaker var, peki şimdi ne yapacağız?
Beləliklə, biz xidmətlərin mənbə kodunu tamamilə dəyişmədən avtomatik söndürmə funksiyasını reallaşdırdıq. Circuit Breaker və yuxarıda təsvir olunmuş Pool Ejection prosedurundan istifadə edərək, resurslar qrupundan tormozlanan konteynerləri çıxara bilərik, onlar normaya gələnə qədər, onların vəziyyətini isə mütəmadi olaraq yoxlaya bilərik – bizim nümunəmizdə, bu, iki dəqiqədir (sleepWindow parametri).
Qeyd edək ki, tətbiqin 503 səhvinə reaksiya vermə qabiliyyəti hələ də onun mənbə kodu səviyyəsində müəyyən edilir. Müxtəlif vəziyyətlərə uyğun tətbiq edilən bir çox Circuit Breaker strategiyaları mövcuddur.
Növbəti yazıda: Istio-da artıq inteqrasiya olunmuş və ya asanlıqla əlavə edilə bilən izləmə və monitorinq haqqında, həmçinin sistemə qəsdən səhvlər daxil etməyi izah edəcəyik.
Mənbə: habr.com
