Ferien er over og vi er tilbake med vårt andre innlegg i Istio Service Mesh-serien.
Dagens tema er Circuit Breaker, som oversatt til russisk elektroteknikk betyr "kretsbryter", i vanlig språkbruk - "kretsbryter". Bare i Istio kobler ikke denne maskinen fra en kortsluttet eller overbelastet krets, men defekte beholdere.
Hvordan dette skal fungere ideelt
Når mikrotjenester administreres av Kubernetes, for eksempel innenfor OpenShift-plattformen, skalerer de automatisk opp og ned avhengig av belastningen. Fordi mikrotjenester kjører i pods, kan det være flere forekomster av en containerisert mikrotjeneste på ett endepunkt, og Kubernetes vil rute forespørsler og belastningsbalanse mellom dem. Og – ideelt sett – skal alt dette fungere perfekt.
Vi husker at mikrotjenester er små og flyktige. Efemeralitet, som her betyr lettheten ved å dukke opp og forsvinne, blir ofte undervurdert. Fødsel og død av en annen forekomst av en mikrotjeneste i en pod er ganske forventede ting, OpenShift og Kubernetes håndterer dette bra, og alt fungerer bra - men igjen i teorien.
Hvordan det egentlig fungerer
Tenk deg nå at en spesifikk forekomst av en mikrotjeneste, det vil si en beholder, har blitt ubrukelig: enten svarer den ikke (feil 503), eller, det som er mer ubehagelig, svarer den, men for sakte. Med andre ord blir det feil eller svarer ikke på forespørsler, men det fjernes ikke automatisk fra bassenget. Hva bør gjøres i dette tilfellet? For å prøve på nytt? Bør jeg fjerne den fra ruteplanen? Og hva betyr "for sakte" - hvor mange er det i tall, og hvem bestemmer dem? Kanskje bare gi det en pause og prøve igjen senere? I så fall, hvor mye senere?
Hva er Pool Ejection i Istio
Og her kommer Istio til unnsetning med sine Circuit Breaker-beskyttelsesmaskiner, som midlertidig fjerner defekte beholdere fra ruting- og lastbalanseringsressurspoolen, og implementerer Pool Ejection-prosedyren.
Ved å bruke en strategi for avvikdeteksjon, oppdager Istio kurvepoder som er ute av linjen og fjerner dem fra ressurspoolen i en spesifisert tidsperiode, kalt et søvnvindu.
For å vise hvordan dette fungerer i Kubernetes på OpenShift-plattformen, la oss starte med et skjermbilde av normalt fungerende mikrotjenester fra eksemplet i depotet
Gjør seg klar for en krasj
Før du gjør Pool Ejection, må du lage en Istio-rutingsregel. La oss si at vi ønsker å fordele forespørsler mellom pods i forholdet 50/50. I tillegg vil vi øke antallet v2-beholdere fra én til to, slik:
oc scale deployment recommendation-v2 --replicas=2 -n tutorial
Nå setter vi en ruteregel slik at trafikken fordeles mellom pods i forholdet 50/50.
Slik ser resultatet av denne regelen ut:
Du kan finne feil med at denne skjermen ikke er 50/50, men 14:9, men over tid vil situasjonen bedre seg.
Gjør en feil
La oss nå deaktivere en av de to v2-beholderne slik at vi har en sunn v1-beholder, en sunn v2-beholder og en defekt v2-beholder:
Retter feilen
Så vi har en defekt container, og det er på tide med Pool Ejection. Ved å bruke en veldig enkel konfigurasjon vil vi ekskludere denne mislykkede beholderen fra alle rutingskjemaer i 15 sekunder i håp om at den vil gå tilbake til en sunn tilstand (enten omstart eller gjenopprett ytelse). Dette er hvordan denne konfigurasjonen ser ut og resultatene av arbeidet:
Som du kan se, brukes ikke lenger den mislykkede v2-beholderen til rutingforespørsler fordi den er fjernet fra bassenget. Men etter 15 sekunder vil den automatisk gå tilbake til bassenget. Faktisk viste vi nettopp hvordan Pool Ejection fungerer.
La oss begynne å bygge arkitektur
Pool Ejection, kombinert med Istios overvåkingsmuligheter, lar deg begynne å bygge et rammeverk for automatisk utskifting av defekte beholdere for å redusere, om ikke eliminere, nedetid og feil.
NASA har ett høyt motto - Failure Is Not an Option, hvis forfatter anses å være flydirektøren
Istio, som vi skrev ovenfor, implementerer konseptet med effektbrytere, som har vist seg godt i den fysiske verden. Og akkurat som en elektrisk strømbryter slår av en problemdel av en krets, åpner Istios programvare Circuit Breaker forbindelsen mellom en strøm av forespørsler og en problembeholder når noe er galt med endepunktet, for eksempel når serveren krasjet eller begynte å ro ned.
Dessuten, i det andre tilfellet er det bare flere problemer, siden bremsene til en container ikke bare forårsaker en kaskade av forsinkelser i tjenestene som får tilgang til den, og som et resultat reduserer ytelsen til systemet som helhet, men genererer også gjentatte forespørsler til en allerede saktegående tjeneste, noe som bare forverrer situasjonen .
Strømbryter i teorien
Circuit Breaker er en proxy som kontrollerer flyten av forespørsler til et endepunkt. Når dette punktet slutter å fungere eller, avhengig av innstillingene som er spesifisert, begynner å avta, bryter proxyen forbindelsen med beholderen. Trafikken blir deretter omdirigert til andre containere, rett og slett på grunn av lastbalansering. Tilkoblingen forblir åpen i et gitt søvnvindu, si to minutter, og regnes deretter som halvåpen. Et forsøk på å sende neste forespørsel bestemmer den videre tilstanden til forbindelsen. Hvis alt er OK med tjenesten, går tilkoblingen tilbake til fungerende tilstand og lukkes igjen. Hvis det fortsatt er noe galt med tjenesten, kobles tilkoblingen fra og dvalevinduet aktiveres på nytt. Slik ser et forenklet Circuit Breaker-tilstandsdiagram ut:
Det er viktig å merke seg her at alt dette skjer på nivå med så å si systemarkitektur. Så på et tidspunkt må du lære applikasjonene dine å fungere med Circuit Breaker, for eksempel å gi en standardverdi som svar eller, hvis mulig, ignorere eksistensen av tjenesten. Et skottmønster brukes til dette, men det er utenfor rammen av denne artikkelen.
Strømbryter i praksis
For eksempel vil vi kjøre to versjoner av vår anbefalingsmikrotjeneste på OpenShift. Versjon 1 vil fungere fint, men i v2 vil vi bygge inn en forsinkelse for å simulere nedgang på serveren. For å se resultatene, bruk verktøyet
siege -r 2 -c 20 -v customer-tutorial.$(minishift ip).nip.io
Alt ser ut til å fungere, men til hvilken pris? Ved første øyekast har vi 100 % tilgjengelighet, men se nærmere – maksimal transaksjonsvarighet er så mye som 12 sekunder. Dette er helt klart en flaskehals og må utvides.
For å gjøre dette vil vi bruke Istio for å eliminere anrop til trege containere. Slik ser den tilsvarende konfigurasjonen ut ved bruk av Circuit Breaker:
Den siste linjen med httpMaxRequestsPerConnection-parameteren signaliserer at forbindelsen med bør kobles fra når du prøver å opprette en annen - en andre - forbindelse i tillegg til den eksisterende. Siden containeren vår simulerer en langsom tjeneste, vil slike situasjoner oppstå med jevne mellomrom, og da vil Istio returnere en 503-feil, men dette er hva beleiring vil vise:
OK, vi har Circuit Breaker, hva er det neste?
Så vi implementerte automatisk avstenging uten å berøre kildekoden til selve tjenestene i det hele tatt. Ved å bruke Circuit Breaker og Pool Ejection-prosedyren beskrevet ovenfor, kan vi fjerne bremsebeholdere fra ressurspoolen til de går tilbake til normalen, og sjekke statusen deres ved en spesifisert frekvens - i vårt eksempel er dette to minutter (sleepWindow-parameter).
Merk at et programs evne til å svare på en 503-feil fortsatt er satt på kildekodenivå. Det er mange strategier for bruk av Circuit Breaker, avhengig av situasjonen.
I neste innlegg: Vi vil dekke sporing og overvåking som allerede er innebygd eller enkelt lagt til Istio, samt hvordan du med vilje introduserer feil i systemet.
Kilde: www.habr.com