Mønster: Microservice Architecture
Context
Du udvikler en virksomhedsapplikation på serversiden. Den skal understøtte en række forskellige klienter inklusive desktop-browsere, mobile browsere og indfødte mobile applikationer. Applikationen kan også udsætte en API, som tredjeparter kan forbruge. Den kan også integreres med andre applikationer via enten webservices eller en meddelelsesmægler. Applikationen håndterer anmodninger (HTTP-anmodninger og meddelelser) ved at udføre forretningslogik adgang til en database udveksling af meddelelser med andre systemer; og returnere et HTML / JSON / XML-svar. Der er logiske komponenter, der svarer til forskellige funktionelle områder i applikationen.
Problem
Hvad er applikationens implementeringsarkitektur?
Styrker
- Der er et team af udviklere, der arbejder med applikationen
- Nye teammedlemmer skal hurtigt blive produktive
- Applikationen skal være let at forstå og ændre
- Du vil øve kontinuerlig implementering af applikationen
- Du skal køre flere forekomster af applikationen på flere maskiner for at opfylde skalerbarhed og tilgængelighedskrav
- Du vil drage fordel af nye teknologier (rammer, programmeringssprog osv.)
Løsning
Definer en arkitektur, der strukturerer applikationen som et sæt løst koblede, samarbejdende tjenester. Denne tilgang svarer til Y-aksen på skalaen. Hver tjeneste er:
- Meget vedligeholdelig og testbar – muliggør ra pid og hyppig udvikling og implementering
- Løst kombineret med andre tjenester – gør det muligt for et team at arbejde uafhængigt det meste af tiden med deres tjenester uden at blive påvirket af ændringer i andre tjenester og uden at påvirke andre tjenester
- Uafhængigt implementerbart – gør det muligt for et team at implementere deres service uden at skulle koordinere med andre teams
- Kan udvikles af et lille team – afgørende for høj produktivitet ved at undgå den store kommunikationschef for store teams
Tjenester kommunikerer ved hjælp af enten synkrone protokoller såsom HTTP / REST eller asynkrone protokoller såsom AMQP. Tjenester kan udvikles og implementeres uafhængigt af hinanden. Hver tjeneste har sin egen database for at afkobles fra andre tjenester. Datakonsistensen mellem tjenester opretholdes ved hjælp af Saga-mønsteret
Hvis du vil vide mere om typen af en tjeneste, skal du læse denne artikel.
Eksempler
Fiktive applikationer til e-handel den
Lad os forestille os, at du bygger en e-handelsapplikation, der tager ordrer fra kunder, verificerer beholdning og tilgængelig kredit og sender dem. Applikationen består af flere komponenter inklusive StoreFrontUI, som implementerer brugergrænsefladen sammen med nogle backend-tjenester til kontrol af kredit, vedligeholdelse af lager- og forsendelsesordrer. Applikationen består af et sæt tjenester.
Vis mig koden
Se eksemplerne på applikationer udviklet af Chris Richardson. Disse eksempler på Github illustrerer forskellige aspekter af mikroservicearkitekturen.
Resulterende kontekst
Fordele
Denne løsning har en række fordele:
- Muliggør kontinuerlig levering og implementering af store, komplekse applikationer.
- Forbedret vedligeholdelsesevne – hver tjeneste er relativt lille og er derfor lettere at forstå og ændre
- Bedre testbarhed – tjenester er mindre og hurtigere at teste
- Bedre implementeringsevne – tjenester kan implementeres uafhængigt
- Det giver dig mulighed for at organisere udviklingsindsatsen omkring flere, autonome teams. Hvert (såkaldt to pizza) hold ejer og er ansvarlig for en eller flere tjenester. Hvert team kan udvikle, teste, implementere og skalere deres tjenester uafhængigt af alle de andre teams.
- Hver mikroservice er relativt lille:
- Lettere for en udvikler at forstå
- IDE er hurtigere, hvilket gør udviklere mere produktive
- Applikationen starter hurtigere, hvilket gør udviklere mere produktive og fremskynder implementeringer
- Forbedret fejlisolering. For eksempel, hvis der er en hukommelseslækage i en tjeneste, vil kun den pågældende tjeneste blive påvirket. De andre tjenester vil fortsat håndtere anmodninger. Til sammenligning kan en fejlbehæftende komponent i en monolitisk arkitektur bringe hele systemet ned.
- Eliminerer enhver langsigtet forpligtelse til en teknologiestak. Når du udvikler en ny tjeneste, kan du vælge en ny teknologiestak. På samme måde kan du omskrive den ved at foretage større ændringer i en eksisterende tjeneste ved hjælp af en ny teknologistak.
Ulemper
Denne løsning har et antal ulemper:
- Udviklere skal håndtere den ekstra kompleksitet ved at oprette et distribueret system:
- Udviklere skal implementere inter-service kommunikationsmekanismen og håndtere delvis fiasko
- Implementering af anmodninger, der spænder over flere tjenester, er vanskeligere
- At teste interaktionen mellem tjenester er mere vanskeligt
- Implementering af anmodninger, der spænder over flere tjenester, kræver omhyggelig koordinering mellem holdene
- Udviklerværktøjer / IDE’er er orienteret om at opbygge monolitiske applikationer og giver ikke eksplicit support til udvikling af distribuerede applikationer.
- Implementeringskompleksitet. I produktionen er der også den operationelle kompleksitet ved implementering og styring af et system, der består af mange forskellige tjenester.
- Øget hukommelsesforbrug. Mikroservicearkitekturen erstatter N monolitiske applikationsforekomster med NxM-tjenesteforekomster. Hvis hver tjeneste kører i sin egen JVM (eller tilsvarende), hvilket normalt er nødvendigt for at isolere forekomsterne, er der overhead på M gange så mange JVM-driftstider. Desuden, hvis hver tjeneste kører på sin egen VM (f.eks. EC2-forekomst), som det er tilfældet hos Netflix, er omkostningerne endnu højere.
Problemer
Der er mange problemer, som du skal løse.
Hvornår skal du bruge mikroservicearkitekturen?
En udfordring ved at bruge denne tilgang er at beslutte, hvornår det giver mening at bruge det. Når man udvikler den første version af en applikation, har du ofte ikke de problemer, som denne tilgang løser. Desuden vil brugen af en detaljeret, distribueret arkitektur bremse udviklingen. Dette kan være et stort problem for nystartede virksomheder, hvis største udfordring ofte er, hvordan man hurtigt udvikler forretningsmodellen og den ledsagende Brug af Y-aksedelinger kan gøre det meget sværere at gentage det hurtigt. Senere, når udfordringen imidlertid er, hvordan man skalerer, og du skal bruge funktionel nedbrydning, kan de sammenfiltrede afhængigheder muligvis gøre det vanskeligt at nedbryde din monolitiske anvendelse i et sæt tjenester.
Sådan nedbrydes applikationen tion til tjenester?
En anden udfordring er at beslutte, hvordan systemet skal opdeles i mikrotjenester. Dette er meget en kunst, men der er en række strategier, der kan hjælpe:
- Nedbryd efter forretningsevne og definer tjenester, der svarer til forretningsmuligheder.
- Nedbryd efter domænestyret design-underdomæne.
- Nedbryd med verb eller brugssag og definer tjenester, der er ansvarlige for bestemte handlinger . for eksempel. en
Shipping Service
, der er ansvarlig for afsendelse af komplette ordrer. - Nedbryd efter substantiver eller ressourcer ved at definere en tjeneste, der er ansvarlig for alle operationer på enheder / ressourcer i en given type. for eksempel. en
Account Service
, der er ansvarlig for administration af brugerkonti.
Ideelt set bør hver tjeneste kun have et lille antal ansvarsområder. (Onkel) Bob Martin taler om at designe klasser ved hjælp af Single Responsibility Principle (SRP). SRP definerer et klasses ansvar som en grund til at ændre sig og siger, at en klasse kun skal have en grund til at ændre. Det er fornuftigt at anvende SRP på service design også.
En anden analogi, der hjælper med design af tjenester, er designet af Unix-hjælpeprogrammer. Unix leverer et stort antal hjælpeprogrammer såsom grep, cat og find. Hvert værktøj gør nøjagtigt en ting, ofte usædvanligt godt, og er beregnet til at blive kombineret med andre hjælpeprogrammer ved hjælp af et shell-script til at udføre komplekse opgaver.
Hvordan opretholdes datakonsistens?
For at sikre løs kobling har hver tjeneste sin egen Vedligeholdelse af datakonsistens mellem tjenester er en udfordring, fordi 2 faseforpligtede / distribuerede transaktioner ikke er en mulighed for mange applikationer. En applikation skal i stedet bruge Sagamønsteret. En tjeneste offentliggør en begivenhed, når dens data ændres. Andre tjenester forbruger den begivenhed og opdaterer deres data. Der er flere måder til pålidelig opdatering af data og udgivelse af begivenheder, herunder hændelsessourcing og Transaktionslog Tailing.
Hvordan implementeres forespørgsler?
En anden udfordring er at implementere forespørgsler, der skal hente data, der ejes af flere tjenester.
- API Komposition og kommandoforespørgsel Ansvarsopdelingsmønstre (CQRS) mønstre.
Der er mange mønstre relateret til mikroservicemønsteret. Den monolitiske arkitektur er et alternativ til mikroservicearkitekturen. De andre mønstre løser problemer, som du vil støde på, når du anvender mikroservicearkitekturen.
- Nedbrydningsmønstre
- Nedbryd efter forretningsevne
- Nedbryd efter underdomæne
- Databasen pr. servicemønster beskriver, hvordan hver tjenesten har sin egen database for at sikre løs kobling.
- API Gateway-mønsteret definerer, hvordan klienter får adgang til tjenesterne i en mikroservicearkitektur.
- Opdagelsesmønstre på klientsiden og serversiden bruges til at dirigere anmodninger om en klient til en tilgængelig serviceinstans i en mikroservicearkitektur.
- Messaging og Remote Procedure Invocation mønstre er to forskellige måder, som tjenester kan kommunikere.
- Den enkelte service pr. vært og flere tjenester pr. vært mønstre er to forskellige implementeringsstrategier.
- Cross-cutting vedrører mønstre: Microservice chassis mønster og ekstern konfiguration
- Test mønstre: Service Component Test og Service Integration Contract Test
- Circuit Breaker
- Adgangstoken
- Observationsmønstre:
- Logaggregation
- Applikationsmetrics
- Auditlogging
- Distribueret sporing
- Undtagelsessporing
- Health check API
- Log implementeringer og ændringer
- UI-mønstre:
- Serversidesidens fragmentsammensætning
- UI-sammensætning på klientsiden
Kendte anvendelser
De fleste store websteder inklusive Netflix, Amazon og eBay har udviklet sig fra en monolitisk arkitektur til en mikroservicearkitektur.
Netflix, som er en meget populær videostreamingtjeneste, der er ansvarlig for op til 30% af internettrafikken, har en serviceorienteret arkitektur i stor skala. De håndterer over en milliard opkald om dagen til deres videostreaming-API fra over 800 forskellige slags enheder. Hver API kalder fans op til i gennemsnit seks kald til backend-tjenester.
Amazon.com havde oprindeligt en to-lags arkitektur. For at skalere migrerede de til en serviceorienteret arkitektur bestående af hundreder af backend-tjenester. Flere applikationer kalder disse tjenester inklusive applikationerne der implementerer Amazon.com-webstedet og webtjenestens API. Amazon.com-webapplikationen ringer til 100-150 tjenester for at få data, der bruges til at oprette en webside.
Auktionswebstedet ebay.com udviklede sig også fra en monolitisk arkitektur til en serviceorienteret arkitektur. Applikationsniveauet består af flere uafhængige applikationer. Hver applikation implementerer forretningslogikken til et specifikt funktionsområde, såsom køb eller salg. Hver applikation bruger X-aksedelinger, og nogle applikationer såsom søgning bruger Z-aksedelinger. eBay.com anvender også en kombination af X-, Y- og Z-stil skalering til database tier.
Der er adskillige andre eksempler på virksomheder, der bruger mikroservicearkitekturen.
Chris Richardson har eksempler på mikrotjenester-baserede applikationer.
Se også
Se min Code Freeze 2018 keynote, som giver en god introduktion til mikroservicearkitekturen.