Breaking free from the Monolith (Norsk)

Og hvordan vi utviklet oss med Microservices

(19. juli 2018)

En monolitisk avgjørende kode-ape

Hos Conio startet det hele med det som ofte kalles en «monolit». Det vil si en enkelt kodebase som inneholder alt av hele applikasjonen: dens frontend-komponenter, backend-komponenter, API-tjenester, bakgrunnsoppgaver; helvete, til og med devops manus. Og det fungerte veldig bra i begynnelsen. Bare et par programvareingeniører som jobber på separate områder av kodebasen (så veldig små sjanser for kodeendringskonflikter), enkle å distribuere. Fullt fokus på å skrive applikasjonsfunksjoner, uten å bekymre deg for mye annet. Hvordan vi nærmet oss distribusjonen? Med bare noen få betakunder som var klar over de kontinuerlige fremskrittene, var det ikke et reelt problem å stenge tjenestene en stund, lansere hele kodebasen (uansett hvor liten eller stor de samlede endringene var, og om de inkluderte databasemigrasjoner), og ta deretter opp tjenestene igjen.

Det var definitivt tilfredsstillende å se et produkt ta form fra bunnen av og motta pris fra sluttkunder. Vi visste imidlertid veldig godt at denne tilnærmingen ikke passer til et moderne Fintech-selskap.

Hva da?

Med de fleste programvare er kundene ganske tolerante. Ja, Whatsapp kan slutte å virke og ha strømbrudd i noen timer: definitivt en plage, men ikke et opplevd problem. Det samme gjelder Pokemon Go eller favorittspillappen din. Imidlertid er ikke tilfelle når det er penger involvert : humørsvingninger hvis du ikke kan logge på bankkontoen din eller ikke er i stand til å foreta handelsoperasjoner. Dette er enda verre når det gjelder cryptocurrency-applikasjoner: folk flest husker beryktede tabber fra fortiden, og når de ikke er i stand til å få tilgang til kryptokurrencyfondene sine selv i kort tid, oppstår det spekulasjoner. Det er rettferdig. Det er pengene dine, og du bør ha lite eller ingen problemer når du vil bruke dem.

Monolitten ovenfor er ikke egnet for et slikt scenario: enhver endring av kodebasen i produksjonen vil kreve full distribusjon, med tilhørende nedetid. Hver dag jobber vi for å forbedre tjenestene våre ved å fikse feil, gjøre grensesnittet vårt enda mer vennlig, fjerne gamle funksjoner og legge til nye som har bedre bruk. Vi slipper ofte disse oppdateringene hver dag, slik at kundene våre kan dra nytte av det, og vi prøver ikke å ha noen innvirkning på kundens opplevelse. Det vil si, uansett hvilken formel vi tar i bak kulissene, må være usynlig for omverdenen (i det minste de fleste ganger). Så vi flyttet vekk fra monolitten og valgte det som ofte kalles «Microservices architecture».

Evolusjon gjennom Microservices

Den massive, tett limte enkeltkodebasen blir nå spaltet i mindre deler, som hver representerer en bestemt tjeneste. Hver gang de kjøres, kommuniserer tjenester med hverandre synkront via standard HTTP-protokoll og asynkront via køer (håndtert for eksempel av RabbitMQ og Apache Kafka).

Interaksjoner i en mikrotjenestearkitektur

Det er ganske utfordrende å begynne å bryte monolitten i mindre komponenter, men det er veldig vel verdt innsatsen. Militært er det veldig likt det Julius Caesar gjorde for å jevnlig styre Gallias store territorium: « del og erobre «.

1) Produktet kan distribueres kontinuerlig. En kodeoppdatering gjelder nå bare for en mikrotjeneste: i de fleste tilfeller kan den umiddelbart distribueres til produksjon og frigis uten innvirkning på kunden

2) Koden er lettere å administrere. Fra et organisasjonsperspektiv endres ting når et team på to programvareingeniører blir et team på 10 programvareingeniører. Det er mer effektivt og med færre kodekonflikter når hvert teammedlem er ansvarlig for sin egen mikroservice.

3) Koden er lettere å vedlikeholde. En Microservices-arkitektur krever av natur definisjonen av et grensesnitt for å kommunisere med den eksterne verdenen (det være seg frontend-appen eller en annen backend-tjeneste), og den er helt isolert fra ethvert annet synspunkt. Dette gjør det mulig å gjennomgå, omforme eller til og med skrive helt om fra bunnen av (til og med på forskjellige språk hvis det er praktisk) enkeltkomponenter i applikasjonen uten å påvirke resten.

4) Ytelsen kan forbedres. Hver mikrotjeneste kan nå bruke sitt mest passende språk. Tunge kryptografiske beregningskomponenter kan for eksempel optimaliseres i C, mens API-tjenester i Python og langvarige oppgaver i Go.

5) Forbedret kodeisolering og sikkerhet. Hver mikrotjeneste kan kjøres i sin egen Docker-container, og gir dermed privilegierisolering, nettverks- og datasegregering og, av største betydning for en vekstfase, et enormt skalerbarhetspotensial.

Er Microservices svaret da?

Selvfølgelig er det ikke noe som heter gratis lunsj. En Microservices-arkitektur kommer også med sitt eget sett med tøffe utfordringer:

1) Operasjonell kompleksitet. DevOps-ingeniører er definitivt nødvendig for å utjevne komplikasjonene i den nye distribusjonsprosessen.

2) Maskinvareoppblåsthet. Mikrotjenester drives ofte i Docker-containere; så snart antallet mikrotjenester øker, blir det mer og mer utfordrende å kjøre hele applikasjonen på samme maskinvare som før.

3) Intercommunication overhead: hver forespørsel må kanskje samhandle med en eller flere forskjellige mikrotjenester gjennom nettverket. Dette kan føre til økt ventetid og kan være utsatt for midlertidige feil. For å implementere elastiske tjenester samt forbedre skalerbarheten i hele systemet, er det nødvendig å flytte interaksjoner til asynkrone meldinger (f.eks. Ved hjelp av Apache Kafka og / eller RabbitMQ)

4) Eventuell konsistens. Dette er sannsynligvis den vanskeligste utfordringen med en Microservices-arkitektur. Gitt en enkelt mikrotjeneste er det mulig å opprette RDBMS-transaksjoner innenfor sine grenser . Dessverre er det imidlertid et vanlig problem i distribuerte arkitekturer å håndtere flere transaksjoner som ikke er innenfor de samme grensene. Som et resultat kan systemet havne i en ulovlig og uopprettelig tilstand. For å avhjelpe slike problemer, vedtar Conio forskjellige strategier:

  1. Etter praksis med Domain Driven Design, dekomponere domene på høyere nivå i underdomener og begrense dem til individuelt avgrensede kontekster ; hver avgrensede kontekst er implementert som en mikrotjeneste, der transaksjonsgrenser blir brukt. Dette løser muligheten for å ha inkonsekvenser for bestemte underdomener.
  2. Implementere idempotente asynkrone interaksjoner, som før eller siden løser inkonsekvenser.
  3. Når det er mulig, unngå handlinger som kan involvere flere underdomener.

5) Kompleks rapportering. Siden hvert underdomener lever i en spesifikk avgrenset kontekst, kan det hende at komplekse rapporter som involverer flere underdomener, trenger å spørre om data fra flere datakilder: dette kan ha negativ innvirkning både på ekspressiviteten til domenene og på systemets skalerbarhet. Her i Conio har vi tatt i bruk en CQRS-arkitektur for å støtte backoffice-aktivitet og forretningsanalyserapporter.

6 ) Loggingssystem. Hvert element i et distribuert system bidrar til opprettelsen av loggen til hele systemet. Det er imidlertid nødvendig å implementere verktøy som kan skape de nødvendige forbindelsene mellom alle slike atskilte logger for å ha en enhetlig logg for hver interaksjon. Her i Conio bruker vi ELK (ElasticSearch, Logstash, Kibana) stack for å lagre og spørre loggdata: hver logg er beriket med de nødvendige korrelasjons-ID-ene som tillater ovennevnte enhetlige logg.

Stopp aldri utviklingen

Vår oppfatning? Å dekomponere den første enkeltkodebasen må sees på som en langsiktig oppgave , med evigvarende forbedringer. På Conio tok det oss et par år hvor vi steg for steg flyttet fra 1 massiv kodebase til over 100 mikrotjenester. Vi har kommet til et punkt der vi føler oss stolte av resultatene, men samtidig fortsetter vi å utforske. Det er flere mulige nye optimaliseringer: å flytte fra Docker Swarm til Kubernetes? Migrere backend-for-frontend-tjenester til serverløse lambdafunksjoner? Bytter du til en full kontinuerlig distribusjonsoperasjonsflyt? Mulighetene er uendelige.

Vi har berørt en rekke emner og teknologier her. I de neste artiklene vil vi dele mer informasjon om funn og fremgang. Hvis du vil, er du velkommen til å kommentere og fortelle oss din erfaring.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *