Ferien er slut, og vi er tilbage med vores andet indlæg i Istio Service Mesh-serien.
Dagens emne er Circuit Breaker, som oversat til russisk elektroteknik betyder "kredsløbsafbryder", i almindeligt sprogbrug - "kredsløbsafbryder". Kun i Istio afbryder denne maskine ikke et kortsluttet eller overbelastet kredsløb, men defekte beholdere.
Hvordan dette skal fungere ideelt
Når mikrotjenester administreres af Kubernetes, for eksempel inden for OpenShift-platformen, skalerer de automatisk op og ned afhængigt af belastningen. Fordi mikrotjenester kører i pods, kan der være flere forekomster af en containeriseret mikrotjeneste på ét slutpunkt, og Kubernetes vil dirigere anmodninger og belastningsbalance mellem dem. Og - ideelt set - alt dette burde fungere perfekt.
Vi husker, at mikrotjenester er små og flygtige. Efemeralitet, som her betyder letheden ved at dukke op og forsvinde, er ofte undervurderet. Fødslen og døden af en anden forekomst af en mikrotjeneste i en pod er ganske forventede ting, OpenShift og Kubernetes håndterer dette godt, og alt fungerer fantastisk - men igen i teorien.
Hvordan det egentlig fungerer
Forestil dig nu, at en specifik forekomst af en mikrotjeneste, det vil sige en beholder, er blevet ubrugelig: enten reagerer den ikke (fejl 503), eller, hvad der er mere ubehagelig, reagerer den, men for langsomt. Med andre ord bliver den fejlagtig eller reagerer ikke på anmodninger, men den fjernes ikke automatisk fra poolen. Hvad skal der gøres i dette tilfælde? For at prøve igen? Skal jeg fjerne det fra routingskemaet? Og hvad betyder "for langsomt" - hvor mange er det i antal, og hvem bestemmer dem? Måske bare give det en pause og prøve igen senere? Hvis ja, hvor meget senere?
Hvad er Pool Ejection i Istio
Og her kommer Istio til undsætning med sine Circuit Breaker-beskyttelsesmaskiner, som midlertidigt fjerner defekte containere fra routing- og belastningsbalanceringsressourcepuljen, der implementerer Pool Ejection-proceduren.
Ved hjælp af en outlier-detektionsstrategi detekterer Istio kurvepods, der er ude af linje, og fjerner dem fra ressourcepuljen i et bestemt tidsrum, kaldet et sleep-vindue.
For at vise, hvordan dette fungerer i Kubernetes på OpenShift-platformen, lad os starte med et skærmbillede af normalt fungerende mikrotjenester fra eksemplet i repository
Forberedelse til fiasko
Før du laver Pool Ejection, skal du oprette en Istio-routingregel. Lad os sige, at vi vil fordele anmodninger mellem pods i forholdet 50/50. Derudover vil vi øge antallet af v2-containere fra én til to, sådan her:
oc scale deployment recommendation-v2 --replicas=2 -n tutorial
Nu sætter vi en ruteregel, så trafikken fordeles mellem pods i forholdet 50/50.
Sådan ser resultatet af denne regel ud:
Du kan finde fejl i, at denne skærm ikke er 50/50, men 14:9, men med tiden vil situationen blive bedre.
At lave en fejl
Lad os nu deaktivere en af de to v2-beholdere, så vi har en sund v1-beholder, en sund v2-beholder og en defekt v2-beholder:
Udbedring af fejlen
Så vi har en defekt container, og det er tid til Pool Ejection. Ved at bruge en meget simpel konfiguration vil vi udelukke denne fejlbehæftede container fra alle routing-skemaer i 15 sekunder i håb om, at den vender tilbage til en sund tilstand (enten genstart eller gendan ydeevne). Sådan ser denne konfiguration ud og resultaterne af dens arbejde:
Som du kan se, bruges den mislykkede v2-beholder ikke længere til routing-anmodninger, fordi den er blevet fjernet fra puljen. Men efter 15 sekunder vender den automatisk tilbage til poolen. Faktisk har vi lige vist, hvordan Pool Ejection fungerer.
Lad os begynde at bygge arkitektur
Pool Ejection, kombineret med Istios overvågningsmuligheder, giver dig mulighed for at begynde at opbygge en ramme til automatisk udskiftning af defekte containere for at reducere, hvis ikke eliminere, nedetid og fejl.
NASA har ét højt motto - Failure Is Not an Option, hvis forfatter anses for at være flyvedirektøren
Istio implementerer, som vi skrev ovenfor, konceptet med afbrydere, som har bevist sig godt i den fysiske verden. Og ligesom en elektrisk afbryder slukker for en problemdel af et kredsløb, åbner Istios software Circuit Breaker forbindelsen mellem en strøm af anmodninger og en problembeholder, når der er noget galt med endepunktet, for eksempel når serveren styrtede ned eller begyndte at sænk farten.
Desuden er der i det andet tilfælde kun flere problemer, da bremserne i en container ikke kun forårsager en kaskade af forsinkelser i de tjenester, der får adgang til den og som et resultat reducerer systemets ydeevne som helhed, men også genererer gentagne henvendelser til en allerede langsomt kørende tjeneste, hvilket kun forværrer situationen .
Circuit Breaker i teorien
Circuit Breaker er en proxy, der styrer strømmen af anmodninger til et slutpunkt. Når dette punkt holder op med at virke eller, afhængigt af de angivne indstillinger, begynder at sænke farten, afbryder proxyen forbindelsen med containeren. Trafikken bliver så omdirigeret til andre containere, simpelthen på grund af lastbalancering. Forbindelsen forbliver åben i et givet søvnvindue, f.eks. to minutter, og betragtes derefter som halvåben. Et forsøg på at sende den næste anmodning bestemmer forbindelsens yderligere tilstand. Hvis alt er OK med tjenesten, vender forbindelsen tilbage til funktionsdygtig tilstand og lukkes igen. Hvis der stadig er noget galt med tjenesten, afbrydes forbindelsen, og dvalevinduet genaktiveres. Sådan ser et forenklet Circuit Breaker-tilstandsdiagram ud:
Det er vigtigt at bemærke her, at alt dette sker på niveau med, så at sige, systemarkitektur. Så på et tidspunkt bliver du nødt til at lære dine applikationer at arbejde med Circuit Breaker, såsom at give en standardværdi som svar eller, hvis det er muligt, ignorere eksistensen af tjenesten. Der bruges et skotmønster til dette, men det ligger uden for denne artikels rammer.
Circuit Breaker i praksis
For eksempel vil vi køre to versioner af vores anbefalingsmikroservice på OpenShift. Version 1 vil fungere fint, men i v2 vil vi indbygge en forsinkelse for at simulere opbremsninger på serveren. Brug værktøjet for at se resultaterne
siege -r 2 -c 20 -v customer-tutorial.$(minishift ip).nip.io
Alt ser ud til at fungere, men til hvilken pris? Ved første øjekast har vi 100 % tilgængelighed, men se nærmere – den maksimale transaktionsvarighed er hele 12 sekunder. Dette er helt klart en flaskehals og skal udvides.
For at gøre dette vil vi bruge Istio til at eliminere opkald til langsomme containere. Sådan ser den tilsvarende konfiguration ud ved brug af Circuit Breaker:
Den sidste linje med parameteren httpMaxRequestsPerConnection signalerer, at forbindelsen med skal afbrydes, når man forsøger at oprette en anden - en anden - forbindelse ud over den eksisterende. Da vores container simulerer en langsom service, vil sådanne situationer opstå med jævne mellemrum, og så vil Istio returnere en 503 fejl, men dette er hvad belejring vil vise:
OK, vi har Circuit Breaker, hvad er det næste?
Så vi implementerede automatisk nedlukning uden at røre ved kildekoden for selve tjenesterne overhovedet. Ved at bruge Circuit Breaker og Pool Ejection proceduren beskrevet ovenfor, kan vi fjerne bremsebeholdere fra ressourcepuljen, indtil de vender tilbage til normalen, og kontrollere deres status ved en specificeret frekvens - i vores eksempel er dette to minutter (sleepWindow parameter).
Bemærk, at et programs evne til at reagere på en 503-fejl stadig er indstillet på kildekodeniveau. Der er mange strategier til at bruge Circuit Breaker, afhængigt af situationen.
I næste indlæg: Vi vil tale om sporing og overvågning, der allerede er indbygget eller nemt tilføjet til Istio, samt hvordan man bevidst indfører fejl i systemet.
Kilde: www.habr.com