Mikrotjenester: Størrelsen betyder noget, selvom du har Kubernetes
19. september i Moskva tog sted det første temamøde HUG (Highload++ User Group), som var dedikeret til mikrotjenester. Der var en præsentation "Operating Microservices: Size Matters, Even If You Have Kubernetes", hvor vi delte Flants omfattende erfaring med at drive projekter med mikroservicearkitektur. Først og fremmest vil det være nyttigt for alle udviklere, der overvejer at bruge denne tilgang i deres nuværende eller fremtidige projekt.
Introduktion video af rapporten (50 minutter, meget mere informativ end artiklen), samt hoveduddraget fra den i tekstform.
NB: Video og præsentation er også tilgængelig i slutningen af dette indlæg.
Indledning
Normalt har en god historie en begyndelse, et hovedplot og en opløsning. Denne rapport er mere som en optakt, og en tragisk sådan. Det er også vigtigt at bemærke, at det giver en outsiders syn på mikrotjenester. operation.
Jeg starter med denne graf, hvis forfatter (i 2015) var Martin Fowler:
Det viser, hvordan produktiviteten begynder at falde i tilfælde af en monolitisk applikation, der når en vis værdi. Mikrotjenester er kendetegnet ved, at den oprindelige produktivitet med dem er lavere, men efterhånden som kompleksiteten øges, er forringelsen af effektiviteten ikke så mærkbar for dem.
Jeg tilføjer til denne graf i tilfælde af brug af Kubernetes:
Hvorfor er en applikation med mikrotjenester bedre? Fordi en sådan arkitektur stiller seriøse krav til arkitekturen, som igen er perfekt dækket af Kubernetes' muligheder. På den anden side vil noget af denne funktionalitet være nyttig for en monolit, især fordi den typiske monolit i dag ikke ligefrem er en monolit (detaljerne kommer senere i rapporten).
Som du kan se, er den endelige graf (når både monolitiske og mikroserviceapplikationer er i infrastrukturen med Kubernetes) ikke meget forskellig fra den originale. Dernæst vil vi tale om applikationer, der betjenes ved hjælp af Kubernetes.
Nyttige og skadelige mikrotjenester
Og her er hovedideen:
Hvad er normal mikroservice arkitektur? Det burde give dig reelle fordele og øge din arbejdseffektivitet. Hvis vi går tilbage til grafen, er den her:
Hvis du ringer til hende nyttig, så vil der være på den anden side af grafen skadelig mikrotjenester (forstyrrer arbejdet):
Tilbage til "hovedideen": skal jeg overhovedet stole på min erfaring? Siden begyndelsen af dette år har jeg kigget 85 projekter. Ikke alle af dem var mikrotjenester (omkring en tredjedel til halvdelen af dem havde sådan en arkitektur), men det er stadig et stort antal. Vi (Flant virksomhed) som outsourcere formår at se en bred vifte af applikationer udviklet både i små virksomheder (med 5 udviklere) og i store (~500 udviklere). En ekstra fordel er, at vi ser disse applikationer leve og udvikle sig gennem årene.
Hvorfor mikrotjenester?
Til spørgsmålet om fordelene ved mikrotjenester er der meget konkret svar fra den allerede nævnte Martin Fowler:
klare grænser for modularitet;
uafhængig implementering;
frihed til at vælge teknologi.
Jeg har talt meget med softwarearkitekter og -udviklere og spurgt, hvorfor de har brug for mikrotjenester. Og jeg lavede min liste over deres forventninger. Her er hvad der skete:
Hvis vi beskriver nogle af punkterne "i fornemmelser", så:
klare grænser for moduler: her har vi en frygtelig monolit, og nu vil alt være pænt arrangeret i Git-depoter, hvor alt er "på hylderne", det varme og det bløde er ikke blandet;
implementeringsuafhængighed: vi vil være i stand til at udrulle tjenester uafhængigt, så udviklingen går hurtigere (udgiv nye funktioner parallelt);
udviklingsuafhængighed: vi kan give denne mikroservice til ét team/udvikler, og den ene til en anden, takket være den kan vi udvikle os hurtigere;
боstørre pålidelighed: hvis der opstår delvis nedbrydning (en mikroservice ud af 20 falder), så vil kun én knap holde op med at virke, og systemet som helhed vil fortsætte med at fungere.
Typisk (skadelig) mikroservicearkitektur
For at forklare, hvorfor virkeligheden ikke er, hvad vi forventer, vil jeg præsentere kollektive et billede af en mikroservicearkitektur baseret på erfaringer fra mange forskellige projekter.
Et eksempel kunne være en abstrakt onlinebutik, der skal konkurrere med Amazon eller i det mindste OZON. Dens mikroservicearkitektur ser sådan ud:
Af en kombination af årsager er disse mikrotjenester skrevet på forskellige platforme:
Da hver mikrotjeneste skal have autonomi, har mange af dem brug for deres egen database og cache. Den endelige arkitektur er som følger:
Hvad er dens konsekvenser?
Fowler har også dette der er en artikel — om "betalingen" for brug af mikrotjenester:
Og vi vil se, om vores forventninger blev indfriet.
Klare grænser for moduler...
Men hvor mange mikrotjenester skal vi egentlig reparere?at udrulle ændringen? Kan vi overhovedet finde ud af, hvordan alt fungerer uden en distribueret sporing (enhver anmodning behandles trods alt af halvdelen af mikrotjenesterne)?
Der er et mønster"stor klump snavs“, og her viste det sig at være en fordelt klump snavs. For at bekræfte dette er her en omtrentlig illustration af, hvordan anmodninger forløber:
Implementeringsuafhængighed...
Teknisk set er det opnået: Vi kan udrulle hver mikroservice separat. Men i praksis skal du tage højde for, at det altid ruller ud mange mikrotjenester, og det skal vi tage hensyn til rækkefølgen af deres udrulning. På en god måde skal vi generelt teste i et separat kredsløb, om vi ruller udgivelsen ud i den rigtige rækkefølge.
Frihed til at vælge teknologi...
Hun er. Bare husk, at frihed ofte grænser til lovløshed. Det er meget vigtigt her ikke at vælge teknologier bare for at "lege" med dem.
Uafhængighed af udvikling...
Hvordan laver man en testloop for hele applikationen (med så mange komponenter)? Men du skal stadig holde det opdateret. Alt dette fører til, at faktiske antal testkredsløb, som vi i princippet kan indeholde, viser sig at være minimal.
Hvad med at implementere alt dette lokalt?.. Det viser sig, at udvikleren ofte udfører sit arbejde selvstændigt, men "tilfældigt", fordi han er tvunget til at vente, indtil kredsløbet er frit til test.
Separat skalering...
Ja, men det er begrænset i det anvendte DBMS-område. I det givne arkitektureksempel vil Cassandra ikke have problemer, men MySQL og PostgreSQL vil.
Боstørre pålidelighed...
Ikke alene bryder fejlen i en mikrotjeneste i virkeligheden ofte hele systemets korrekte funktion, men der er også et nyt problem: at gøre enhver mikroservice fejltolerant er meget vanskelig. Fordi mikrotjenester bruger forskellige teknologier (memcache, Redis osv.), skal du for hver enkelt gennemtænke alt og implementere det, hvilket selvfølgelig er muligt, men kræver enorme ressourcer.
Belastningsmålbarhed...
Det her er rigtig godt.
Mikrotjenesters "lethed"...
Vi har ikke kun enorme netværk overhead (anmodninger om DNS formerer sig osv.), men også på grund af de mange underforespørgsler, vi startede replikere data (store caches), hvilket førte til en betydelig mængde lager.
Og her er resultatet af at leve op til vores forventninger:
Men det er ikke alt!
Fordi:
Vi får højst sandsynligt brug for en beskedbus.
Hvordan laver man en konsekvent backup på det rigtige tidspunkt? Den eneste ene реальный muligheden er at slukke for trafikken for dette. Men hvordan gør man dette i produktionen?
Hvis vi taler om at støtte flere regioner, så er det en meget arbejdskrævende opgave at organisere bæredygtighed i hver af dem.
Problemet med at foretage centraliserede ændringer opstår. For eksempel, hvis vi skal opdatere PHP-versionen, bliver vi nødt til at forpligte os til hvert lager (og der er dusinvis af dem).
Væksten i operationel kompleksitet er umiddelbart eksponentiel.
Hvad skal man gøre med alt dette?
Start med en monolitisk applikation. Fowlers oplevelse Han taler at næsten alle vellykkede mikroserviceapplikationer startede som en monolit, der blev for stor og derefter blev brudt. Samtidig oplevede næsten alle systemer bygget som mikrotjenester lige fra begyndelsen før eller siden alvorlige problemer.
En anden værdifuld tanke er, at for at et projekt med en mikroservicearkitektur skal lykkes, skal du vide det godt og fagområde, og hvordan man laver mikrotjenester. Og den bedste måde at lære et fagområde på er at lave en monolit.
Men hvad hvis vi allerede er i denne situation?
Det første skridt til at løse ethvert problem er at være enig i det og forstå, at det er et problem, at vi ikke ønsker at lide mere.
Hvis vi i tilfælde af en forvokset monolit (når vi er løbet tør for muligheden for at købe yderligere ressourcer til den), skærer den, så viser den modsatte historie sig i dette tilfælde: når overdrevne mikrotjenester ikke længere hjælper, men hindrer - skær overskydende af og forstørre!
For eksempel, for det kollektive billede diskuteret ovenfor...
Slip af med de mest tvivlsomme mikrotjenester:
Kombiner alle mikrotjenester, der er ansvarlige for frontend-generering:
... i én mikrotjeneste, skrevet i ét (moderne og normalt, som du selv tror) sprog/ramme:
Det vil have én ORM (én DBMS) og først et par applikationer:
... men generelt kan du overføre meget mere dertil og få følgende resultat:
Desuden kører vi alt dette i Kubernetes i separate instanser, hvilket betyder, at vi stadig kan måle belastningen og skalere dem separat.
sammenfattende
Se på det større billede. Meget ofte opstår alle disse problemer med mikrotjenester, fordi nogen tog deres opgave, men ville "lege med mikrotjenester".
I ordet "mikrotjenester" er "mikro"-delen overflødig.. De er "mikro" kun fordi de er mindre end en enorm monolit. Men tænk ikke på dem som noget lille.
Og for en sidste tanke, lad os vende tilbage til det originale diagram:
En note skrevet på den (øverst til højre) bunder i, at kompetencerne hos det team, der laver dit projekt, er altid primære — de vil spille en nøglerolle i dit valg mellem mikrotjenester og en monolit. Hvis holdet ikke har nok færdigheder, men det begynder at lave mikrotjenester, vil historien helt sikkert være fatal.
Videoer og dias
Video fra talen (~50 minutter; desværre formidler den ikke de besøgendes mange følelser, som i høj grad afgjorde stemningen i rapporten, men sådan er det):