Mønster: Microservice Architecture (Norsk)
Context
Du utvikler en bedriftsapplikasjon på server-siden. Den må støtte en rekke forskjellige klienter, inkludert stasjonære nettlesere, mobile nettlesere og innfødte mobilapplikasjoner. Applikasjonen kan også utsette et API for tredjeparter å konsumere. Det kan også integreres med andre applikasjoner via enten nettjenester eller en meldingsmegler. Applikasjonen håndterer forespørsler (HTTP-forespørsler og meldinger) ved å utføre forretningslogikk; tilgang til en database; utveksling av meldinger med andre systemer; og returnere et HTML / JSON / XML-svar. Det er logiske komponenter som tilsvarer forskjellige funksjonelle områder av applikasjonen.
Problem
Hva er applikasjonens distribusjonsarkitektur?
Styrker
- Det er et team av utviklere som jobber med applikasjonen
- Nye teammedlemmer må raskt bli produktive
- Applikasjonen må være lett å forstå og endre
- Du vil øve på kontinuerlig distribusjon av applikasjonen
- Du må kjøre flere forekomster av applikasjonen på flere maskiner for å tilfredsstille krav til skalerbarhet og tilgjengelighet
- Du vil dra nytte av nye teknologier (rammer, programmeringsspråk, osv.)
Løsning
Definer en arkitektur som strukturer applikasjonen som et sett med løst koblet, samarbeidende tjenester. Denne tilnærmingen tilsvarer Y-aksen til Scale Cube. Hver tjeneste er:
- Svært vedlikeholdbar og testbar – muliggjør ra pid og hyppig utvikling og distribusjon
- Løst kombinert med andre tjenester – gjør det mulig for et team å jobbe uavhengig mesteparten av tiden på tjenestene sine uten å bli påvirket av endringer i andre tjenester og uten å påvirke andre tjenester
- Uavhengig distribuerbar – gjør det mulig for et team å distribuere tjenesten sin uten å måtte koordinere med andre team
- Kan utvikles av et lite team – avgjørende for høy produktivitet ved å unngå det store kommunikasjonssjefen for store team
Tjenester kommuniserer ved hjelp av enten synkrone protokoller som HTTP / REST eller asynkrone protokoller som AMQP. Tjenester kan utvikles og distribueres uavhengig av hverandre. Hver tjeneste har sin egen database for å være frakoblet fra andre tjenester. Datakonsistensen mellom tjenestene opprettholdes ved hjelp av Saga-mønsteret
For å lære mer om arten av en tjeneste, vennligst les denne artikkelen.
Eksempler
Fiktive e-handelsapplikasjoner på
La oss forestille oss at du bygger et e-handelsapplikasjon som tar imot bestillinger fra kunder, verifiserer lager og tilgjengelig kreditt, og sender dem. Applikasjonen består av flere komponenter, inkludert StoreFrontUI, som implementerer brukergrensesnittet , sammen med noen backend-tjenester for å sjekke kreditt, vedlikeholde lager- og forsendelsesordrer. Applikasjonen består av et sett med tjenester.
Vis meg koden
Se eksemplene på applikasjoner utviklet av Chris Richardson. Disse eksemplene på Github illustrerer forskjellige aspekter av mikroservicearkitekturen.
Resulterende kontekst
Fordeler
Denne løsningen har en rekke fordeler:
- Muliggjør kontinuerlig levering og distribusjon av store, komplekse applikasjoner.
- Forbedret vedlikeholdsevne – hver tjeneste er relativt liten og det er lettere å forstå og endre
- Bedre testbarhet – tjenester er mindre og raskere å teste
- Bedre distribusjonsevne – tjenester kan distribueres uavhengig
- Det lar deg organisere utviklingsarbeidet rundt flere, autonome team. Hvert (såkalt to pizza) team eier og er ansvarlig for en eller flere tjenester. Hvert team kan utvikle, teste, distribuere og skalere sine tjenester uavhengig av alle de andre teamene.
- Hver mikrotjeneste er relativt liten:
- Enklere for en utvikler for å forstå
- IDE er raskere og gjør utviklere mer produktive
- Applikasjonen starter raskere, noe som gjør utviklere mer produktive, og fremskynder distribusjoner
- Forbedret feilisolering. For eksempel, hvis det er en minnelekkasje i en tjeneste, vil bare den tjenesten bli påvirket. De andre tjenestene vil fortsette å håndtere forespørsler. Til sammenligning kan en komponent med dårlig oppførsel i en monolitisk arkitektur få ned hele systemet.
- Eliminerer enhver langsiktig forpliktelse til en teknologibunke. Når du utvikler en ny tjeneste kan du velge en ny teknologibunke. På samme måte kan du omskrive den ved å gjøre store endringer i en eksisterende tjeneste ved hjelp av en ny teknologibunke.
Ulemper
Denne løsningen har en rekke ulemper:
- Utviklere må håndtere den ekstra kompleksiteten ved å lage et distribuert system:
- Utviklere må implementere kommunikasjonssystemet mellom tjenestene og håndtere delvis feil
- Å implementere forespørsler som spenner over flere tjenester er vanskeligere
- Det er mer å teste samspillet mellom tjenestene vanskelig
- Å implementere forespørsler som spenner over flere tjenester krever nøye koordinering mellom teamene
- Utviklerverktøy / IDEer er orientert om å bygge monolitiske applikasjoner og gir ikke eksplisitt støtte for utvikling av distribuerte applikasjoner.
- Installasjonskompleksitet. I produksjonen er det også den operasjonelle kompleksiteten ved å distribuere og administrere et system som består av mange forskjellige tjenester.
- Økt minneforbruk. Mikrotjenestearkitekturen erstatter N-monolitiske applikasjonsforekomster med NxM-tjenesteforekomster. Hvis hver tjeneste kjører i sin egen JVM (eller tilsvarende), som vanligvis er nødvendig for å isolere forekomster, er det overhead på M ganger så mange JVM-kjøretider. Dessuten, hvis hver tjeneste kjører på sin egen VM (f.eks. EC2-forekomst), som det er tilfelle hos Netflix, er overhead enda høyere.
Problemer
Det er mange problemer du må løse.
Når skal du bruke mikrotjenestearkitekturen?
En utfordring med å bruke denne tilnærmingen er å avgjøre når det er fornuftig å bruke den. Når du utvikler den første versjonen av en applikasjon, har du ofte ikke problemene som denne tilnærmingen løser. Dessuten vil bruk av en forseggjort, distribuert arkitektur redusere utviklingen. Dette kan være et stort problem for nyetablerere hvis største utfordring ofte er hvordan man raskt utvikler forretningsmodellen og tilhørende Å bruke splittelser på Y-aksen kan gjøre det mye vanskeligere å iterere raskt. Senere, men når utfordringen er hvordan du skalerer og du trenger å bruke funksjonell nedbrytning, kan de sammenfiltrede avhengighetene gjøre det vanskelig å spalte din monolitiske applikasjon til et sett med tjenester.
Hvordan spaltes applikasjonen tion in services?
En annen utfordring er å bestemme hvordan man skal dele systemet i mikrotjenester. Dette er veldig mye en kunst, men det er en rekke strategier som kan hjelpe:
- Nedbryt etter forretningsevne og definer tjenester som tilsvarer forretningsevner.
- Nedbryt etter domenedrevet design-underdomener.
- Nedbryt med verb eller bruk sak og definer tjenester som er ansvarlige for bestemte handlinger . f.eks. en
Shipping Service
som er ansvarlig for å sende fullstendige ordrer. - Nedbryt etter substantiv eller ressurser ved å definere en tjeneste som er ansvarlig for all operasjon på enheter / ressurser for en gitt type. f.eks. en
Account Service
som er ansvarlig for administrering av brukerkontoer.
Ideelt sett bør hver tjeneste bare ha et lite sett med ansvar. (Onkel) Bob Martin snakker om å designe klasser ved bruk av Single Responsibility Principle (SRP). SRP definerer et klasseansvar som en grunn til å endre, og sier at en klasse bare skal ha en grunn til å endre. Det er fornuftig å bruke SRP på tjenestedesign også.
En annen analogi som hjelper med tjenestedesign er utformingen av Unix-verktøy. Unix tilbyr et stort antall verktøy som grep, cat og find. Hvert verktøy gjør akkurat en ting, ofte eksepsjonelt bra, og er ment å bli kombinert med andre verktøy ved hjelp av et skallskript for å utføre komplekse oppgaver.
Hvordan opprettholder datakonsistens?
For å sikre løs kobling har hver tjeneste sin egen Å opprettholde datakonsistens mellom tjenestene er en utfordring fordi to fasekommisjonerte / distribuerte transaksjoner ikke er det et alternativ for mange applikasjoner. Et program må i stedet bruke Saga-mønsteret. En tjeneste publiserer en hendelse når dataene endres. Andre tjenester bruker den hendelsen og oppdaterer dataene. Det er flere måter å pålitelig oppdatere data på og publisere hendelser, inkludert hendelsessourcing og Transaksjonslogg.
Hvordan implementere spørringer?
En annen utfordring er å implementere spørsmål som trenger å hente data som eies av flere tjenester.
- API Composition and Command Query Responsibility Segregation (CQRS) mønstre.
Det er mange mønstre relatert til mikroservicemønsteret. Den monolitiske arkitekturen er et alternativ til mikrotjenestearkitekturen. De andre mønstrene løser problemer du vil støte på når du bruker mikrotjenestearkitekturen.
- Dekomponeringsmønstre
- Nedbryt etter forretningsevne
- Nedbryt etter underdomener
- Databasen per tjenestemønster beskriver hvordan hver tjenesten har sin egen database for å sikre løs kobling.
- API Gateway-mønsteret definerer hvordan klienter får tilgang til tjenestene i en mikroservicearkitektur.
- Oppdagelsesmønstrene på klientsiden og serversiden blir brukt til å dirigere forespørsler om en klient til en tilgjengelig tjenesteforekomst i en mikroservicearkitektur.
- Meldings- og fjernprosedyreinnkallingsmønstrene er to forskjellige måter som tjenester kan kommunisere på.
- Mønstrene for enkelt tjeneste per vert og flere tjenester per vert to forskjellige distribusjonsstrategier.
- Tverrgående mønstre: Microservice-chassismønster og ekstern konfigurasjon
- Testmønstre: Service Component Test og Service Integration Contract Test
- Circuit Bryter
- Tilgangstoken
- Observasjonsmønstre:
- Loggaggregering
- Applikasjonsberegninger
- Revisjonslogging
- Distribuert sporing
- Unntakssporing
- API for helsekontroll
- Logg distribusjoner og endringer
- UI-mønstre:
- Sammensetning av fragmenter på serversiden
- UI-sammensetning på klientsiden
Kjente bruksområder
De fleste store nettsteder, inkludert Netflix, Amazon og eBay, har utviklet seg fra en monolitisk arkitektur til en mikroservicearkitektur.
Netflix, som er en veldig populær videostreamingtjeneste som er ansvarlig for opptil 30% av internettrafikken, har en stor, serviceorientert arkitektur. De håndterer over en milliard samtaler per dag til deres videostreaming-API fra over 800 forskjellige typer enheter. Hver API kaller fans til et gjennomsnitt på seks samtaler til backend-tjenester.
Amazon.com hadde opprinnelig en to-lags arkitektur. For å skalere migrerte de til en serviceorientert arkitektur bestående av hundrevis av backend-tjenester. Flere applikasjoner kaller disse tjenestene inkludert applikasjonene som implementerer Amazon.com-nettstedet og webtjenesten API. Amazon.com-nettsøknaden ringer 100-150 tjenester for å få data som brukes til å bygge en webside.
Auksjonsnettstedet ebay.com utviklet seg også fra en monolitisk arkitektur til en serviceorientert arkitektur. Applikasjonsnivået består av flere uavhengige applikasjoner. Hver applikasjon implementerer forretningslogikken for et bestemt funksjonsområde, for eksempel kjøp eller salg. Hver applikasjon bruker X-aksedelinger og noen applikasjoner, for eksempel søk, bruker Z-aksedelinger. eBay.com bruker også en kombinasjon av X-, Y- og Z-stil skalering til databaselag.
Det er mange andre eksempler på selskaper som bruker mikroservicearkitekturen.
Chris Richardson har eksempler på mikrotjenestebaserte applikasjoner.
Se også
Se hovedfilen til Code Freeze 2018, som gir en god introduksjon til mikroservicearkitekturen.