Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

19. september i Moskva fant sted det første tematiske møtet HUG (Highload++ User Group), som var dedikert til mikrotjenester. Det var en presentasjon «Operating Microservices: Size Matters, Even If You Have Kubernetes», der vi delte Flants omfattende erfaring med å drive prosjekter med mikrotjenestearkitektur. Først av alt vil det være nyttig for alle utviklere som tenker på å bruke denne tilnærmingen i sitt nåværende eller fremtidige prosjekt.

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

Introduserer video av rapporten (50 minutter, mye mer informativ enn artikkelen), samt hovedutdraget fra den i tekstform.

NB: Video og presentasjon er også tilgjengelig på slutten av dette innlegget.

Innledning

Vanligvis har en god historie en begynnelse, et hovedplott og en oppløsning. Denne rapporten er mer som et forspill, og en tragisk en. Det er også viktig å merke seg at det gir en utenforståendes syn på mikrotjenester. utnyttelse.

Jeg starter med denne grafen, forfatteren av denne (i 2015) var Martin Fowler:

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

Den viser hvordan, i tilfelle av en monolitisk applikasjon som når en viss verdi, begynner produktiviteten å synke. Mikrotjenester er forskjellige ved at den opprinnelige produktiviteten med dem er lavere, men etter hvert som kompleksiteten øker, er ikke degraderingen i effektivitet så merkbar for dem.

Jeg vil legge til denne grafen for bruk av Kubernetes:

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

Hvorfor er en applikasjon med mikrotjenester bedre? Fordi en slik arkitektur stiller alvorlige krav til arkitekturen, som igjen er perfekt dekket av Kubernetes evner. På den annen side vil noe av denne funksjonaliteten være nyttig for en monolitt, spesielt fordi den typiske monolitten i dag ikke akkurat er en monolitt (detaljer kommer senere i rapporten).

Som du kan se, er den endelige grafen (når både monolittiske og mikrotjenesteapplikasjoner er i infrastrukturen med Kubernetes) ikke veldig forskjellig fra den originale. Deretter vil vi snakke om applikasjoner som drives med Kubernetes.

Nyttige og skadelige mikrotjenester

Og her er hovedideen:

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

Hva er normal mikrotjenestearkitektur? Det bør gi deg reelle fordeler, øke arbeidseffektiviteten. Hvis vi går tilbake til grafen, er den her:

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

Hvis du ringer henne nyttig, så vil det være på den andre siden av grafen skadelig mikrotjenester (forstyrrer arbeidet):

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

Tilbake til "hovedideen": bør jeg stole på min erfaring i det hele tatt? Siden begynnelsen av dette året har jeg sett 85 prosjekter. Ikke alle av dem var mikrotjenester (omtrent en tredjedel til halvparten av dem hadde en slik arkitektur), men dette er fortsatt et stort antall. Vi (Flant-selskap) som outsourcere klarer å se et bredt utvalg av applikasjoner utviklet både i små selskaper (med 5 utviklere) og i store (~500 utviklere). En ekstra fordel er at vi ser disse applikasjonene leve og utvikle seg gjennom årene.

Hvorfor mikrotjenester?

Til spørsmålet om fordelene med mikrotjenester er det veldig spesifikt svar fra den allerede nevnte Martin Fowler:

  1. klare grenser for modularitet;
  2. uavhengig distribusjon;
  3. frihet til å velge teknologi.

Jeg har snakket mye med programvarearkitekter og utviklere og spurt hvorfor de trenger mikrotjenester. Og jeg laget min liste over forventningene deres. Her er hva som skjedde:

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

Hvis vi beskriver noen av punktene "i sensasjoner", så:

  • klare grenser for moduler: her har vi en forferdelig monolitt, og nå vil alt være pent ordnet i Git-depoter, der alt er "på hyllene", det varme og det myke er ikke blandet;
  • distribusjonsuavhengighet: vi vil kunne rulle ut tjenester uavhengig slik at utviklingen går raskere (publisere nye funksjoner parallelt);
  • utviklingsuavhengighet: vi kan gi denne mikrotjenesten til ett team/utvikler, og den ene til en annen, takket være dette kan vi utvikle oss raskere;
  • боstørre pålitelighet: hvis delvis degradering oppstår (en mikrotjeneste av 20 faller), vil bare én knapp slutte å fungere, og systemet som helhet vil fortsette å fungere.

Typisk (skadelig) mikrotjenestearkitektur

For å forklare hvorfor virkeligheten ikke er det vi forventer, vil jeg presentere kollektiv et bilde av en mikrotjenestearkitektur basert på erfaring fra mange ulike prosjekter.

Et eksempel kan være en abstrakt nettbutikk som skal konkurrere med Amazon eller i det minste OZON. Mikrotjenestearkitekturen ser slik ut:

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

Av en kombinasjon av årsaker er disse mikrotjenestene skrevet på forskjellige plattformer:

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

Siden hver mikrotjeneste må ha autonomi, trenger mange av dem sin egen database og cache. Den endelige arkitekturen er som følger:

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

Hva er dens konsekvenser?

Fowler har dette også det er en artikkel – om "betalingen" for bruk av mikrotjenester:

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

Og vi får se om forventningene våre ble innfridd.

Tydelige grenser for moduler...

Men hvor mange mikrotjenester trenger vi egentlig å fikse?å rulle ut endringen? Kan vi til og med finne ut hvordan alt fungerer uten en distribuert sporing (tross alt blir enhver forespørsel behandlet av halvparten av mikrotjenestene)?

Det er et mønster"stor klump med skitt“, og her viste det seg å være en fordelt klump med skitt. For å bekrefte dette, her er en omtrentlig illustrasjon av hvordan forespørsler går:

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

Implementeringsuavhengighet...

Teknisk sett er det oppnådd: Vi kan rulle ut hver mikrotjeneste separat. Men i praksis må du ta hensyn til at det alltid ruller ut mange mikrotjenester, og vi må ta hensyn til det rekkefølgen på utrullingen. På en god måte må vi generelt teste i en egen krets om vi ruller ut utgivelsen i riktig rekkefølge.

Frihet til å velge teknologi...

Hun er. Bare husk at frihet ofte grenser til lovløshet. Det er veldig viktig her å ikke velge teknologier bare for å "leke" med dem.

Uavhengig av utvikling...

Hvordan lage en testløkke for hele applikasjonen (med så mange komponenter)? Men du må fortsatt holde den oppdatert. Alt dette fører til det faktum at faktisk antall testkretser, som vi i prinsippet kan inneholde, viser seg å være minimal.

Hva med å distribuere alt dette lokalt?.. Det viser seg at utvikleren ofte gjør arbeidet sitt uavhengig, men "tilfeldig", fordi han er tvunget til å vente til kretsen er fri for testing.

Separat skalering...

Ja, men det er begrenset i området for DBMS som brukes. I det gitte arkitektureksemplet vil ikke Cassandra ha problemer, men MySQL og PostgreSQL vil.

Боstørre pålitelighet...

Ikke bare bryter feilen til en mikrotjeneste i virkeligheten ofte den korrekte funksjonen til hele systemet, men det er også et nytt problem: å gjøre hver mikrotjeneste feiltolerant er veldig vanskelig. Fordi mikrotjenester bruker forskjellige teknologier (memcache, Redis, etc.), for hver må du tenke gjennom alt og implementere det, noe som selvfølgelig er mulig, men krever enorme ressurser.

Lastmålbarhet...

Dette er veldig bra.

"Lettheten" til mikrotjenester ...

Vi har ikke bare enorme nettverksoverhead (forespørsler om DNS multipliseres osv.), men også på grunn av de mange underspørringene vi startet replikere data (butikkcacher), noe som førte til en betydelig mengde lagring.

Og her er resultatet av å oppfylle våre forventninger:

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

Men det er ikke alt!

Fordi:

  • Mest sannsynlig trenger vi en meldingsbuss.
  • Hvordan lage en konsistent sikkerhetskopi til rett tid? Den eneste ekte alternativet er å slå av trafikk for dette. Men hvordan gjør man dette i produksjonen?
  • Hvis vi snakker om å støtte flere regioner, så er det en svært arbeidskrevende oppgave å organisere bærekraft i hver av dem.
  • Problemet med å gjøre sentraliserte endringer oppstår. For eksempel, hvis vi trenger å oppdatere PHP-versjonen, må vi forplikte oss til hvert depot (og det er dusinvis av dem).
  • Veksten i operasjonell kompleksitet er direkte eksponentiell.

Hva skal man gjøre med alt dette?

Start med en monolittisk applikasjon. Fowlers erfaring говорит at nesten alle vellykkede mikrotjenesteapplikasjoner startet som en monolitt som ble for stor og deretter ble ødelagt. Samtidig opplevde nesten alle systemer bygget som mikrotjenester helt fra starten før eller siden alvorlige problemer.

En annen verdifull tanke er at for at et prosjekt med en mikrotjenestearkitektur skal lykkes, må du vite det veldig godt og fagområde, og hvordan lage mikrotjenester. Og den beste måten å lære et fagområde på er å lage en monolitt.

Men hva om vi allerede er i denne situasjonen?

Det første trinnet for å løse ethvert problem er å være enig med det og forstå at det er et problem, at vi ikke ønsker å lide lenger.

Hvis vi, når det gjelder en overgrodd monolitt (når vi har gått tom for muligheten til å kjøpe ekstra ressurser for den), kutter den, så viser den motsatte historien seg i dette tilfellet: når overdreven mikrotjenester ikke lenger hjelper, men hindrer - kutt av overflødig og forstørre!

For eksempel, for det kollektive bildet diskutert ovenfor...

Bli kvitt de mest tvilsomme mikrotjenestene:

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

Kombiner alle mikrotjenester som er ansvarlige for frontend-generering:

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

... til én mikrotjeneste, skrevet i ett (moderne og normalt, som du selv tror) språk/rammeverk:

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

Den vil ha en ORM (en DBMS) og først et par applikasjoner:

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

... men generelt kan du overføre mye mer dit og få følgende resultat:

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

Dessuten kjører vi alt dette i Kubernetes i separate instanser, noe som betyr at vi fortsatt kan måle belastningen og skalere dem separat.

Å oppsummere

Se på det større bildet. Svært ofte oppstår alle disse problemene med mikrotjenester fordi noen tok oppgaven deres, men ønsket å "leke med mikrotjenester".

I ordet "mikrotjenester" er "mikro"-delen overflødig.. De er "mikro" bare fordi de er mindre enn en enorm monolitt. Men ikke tenk på dem som noe lite.

Og for en siste tanke, la oss gå tilbake til det opprinnelige diagrammet:

Mikrotjenester: Størrelsen betyr noe, selv om du har Kubernetes

En lapp skrevet på den (øverst til høyre) koker ned til det faktum at ferdighetene til teamet som lager prosjektet ditt er alltid primære — de vil spille en nøkkelrolle i ditt valg mellom mikrotjenester og en monolitt. Hvis teamet ikke har nok ferdigheter, men det begynner å lage mikrotjenester, vil historien definitivt være fatal.

Videoer og lysbilder

Video fra talen (~50 minutter; dessverre formidler den ikke de mange følelsene til de besøkende, som i stor grad avgjorde stemningen i rapporten, men det er slik det er):

Presentasjon av rapporten:

PS

Andre rapporter på bloggen vår:

Du kan også være interessert i følgende publikasjoner:

Kilde: www.habr.com

Legg til en kommentar