Breaking free from the Monolith

Og hvordan vi udviklede os med Microservices

(19. jul. 2018)

En monolit-herskende kodeaber

Hos Conio startede det hele med det, der almindeligvis kaldes en “monolit”. Det vil sige en enkelt kodebase, der indeholder alt fra den fulde applikation: dens frontend-komponenter, backend-komponenter, API-tjenester, baggrundsopgaver; helvede, devops selv scripts. Og det fungerede meget godt i starten. Kun et par softwareingeniører, der arbejder på separate områder af kodebasen (så meget små chancer for kodeændringskonflikter), er lette at implementere. Fuldt fokus på at skrive applikationsfunktioner uden at bekymre dig om meget andet. Hvordan vi nærmede os implementeringen? Med kun få beta-kunder, der var opmærksomme på de igangværende fremskridt, var det ikke et rigtigt problem at lukke tjenester i et stykke tid og udrulle den fulde kodebase (uanset hvor lille eller stor de samlede ændringer var, og om de inkluderede databaseoverførsler) og bring derefter tjenester op igen.

Det var bestemt tilfredsstillende at se et produkt tage form fra bunden og modtage påskønnelser fra slutkunder. Vi vidste imidlertid meget godt, at denne tilgang ikke passer til et moderne Fintech-firma.

Hvad så?

Med de fleste softwareapplikationer er kunderne ret tolerante. Ja, Whatsapp stopper muligvis med at arbejde og har afbrydelse, der varer i et par timer: bestemt en gener, men ikke et opfattet problem. Det samme gælder Pokemon Go eller din yndlingsspil-app. det er dog ikke tilfældet, når der er penge involveret : humørsvingninger, hvis du ikke kan logge ind på din bankkonto eller ikke er i stand til foretage handelsoperationer. Dette er endnu værre i tilfælde af kryptokurrencyapplikationer: de fleste husker berygtede fejl i fortiden, og når de ikke er i stand til at få adgang til deres kryptokurrencyfonde selv i en kort periode, opstår der spekulationer. Det er retfærdigt. Det er dine penge, og du skal have lidt eller intet problem, når du vil bruge dem.

Monolitten ovenfor er ikke egnet til et sådant scenario: enhver ændring af kodebasen i produktionen vil kræve en fuld implementering, med tilhørende nedetid. Hver dag arbejder vi for at forbedre vores tjenester ved at rette fejl, gøre vores interface endnu mere venligt, fjerne gamle funktioner og tilføje nye, der har bedre brug. Vi frigiver ofte disse opdateringer dagligt, så vores kunder kan få øjeblikkelig fordel, og vi bestræber os på ikke at have nogen indflydelse på kundens oplevelse. Det vil sige, uanset hvilken formel vi sammensætter bag kulisserne, skal være usynlig for omverdenen (i det mindste de fleste gange). Så vi flyttede væk fra monolitten og valgte det, der almindeligvis kaldes “Microservices architecture”.

Evolution gennem Microservices

Den massive, fastlimede enkeltkodebase nedbrydes nu i mindre dele, som hver især repræsenterer en bestemt tjeneste. Når de udføres, kommunikerer tjenester med hinanden synkront via standard HTTP-protokol og asynkront via køer (håndteres for eksempel af RabbitMQ og Apache Kafka).

Interaktioner i en mikrotjenestearkitektur

Det er ret udfordrende at begynde at bryde monolit i mindre komponenter, men det er meget værd indsatsen. Militært ligner det meget, hvad Julius Caesar gjorde for støt at herske over Gallias store territorium: “ del og erobre “.

1) Produktet kan løbende implementeres. En kodeopdatering gælder nu kun for en mikroservice: i de fleste tilfælde kan den straks distribueres til produktion og frigives uden indvirkning på kunden

2) Koden er lettere at administrere. Fra et firmaorganisationsperspektiv ændrer ting sig, når et team på 2 softwareingeniører bliver et team på 10 softwareingeniører. Det er mere effektivt og med færre kodekonflikter, når hvert teammedlem er ansvarlig for sin egen mikroservice.

3) Koden er lettere at vedligeholde. En mikroservicearkitektur kræver af natur definitionen af ​​en grænseflade for at kommunikere med den eksterne verden (det være sig frontend-appen eller en anden backend-tjeneste), og den er helt isoleret fra ethvert andet synspunkt. Dette giver mulighed for at gennemgå, re-designe eller endog fuldstændig omskrive fra bunden (selv på forskellige sprog, hvis det er praktisk) enkeltkomponenter i applikationen uden at påvirke resten.

4) Ydeevnen kan forbedres. Hver mikroservice kan nu bruge sit mest passende sprog. Tunge kryptografiske beregningskomponenter kan for eksempel optimeres i C, mens API-tjenester i Python og langvarige opgaver i Go.

5) Forbedret kodeisolering og sikkerhed. Hver mikroservice kan køres i sin egen Docker-container, hvilket giver privilegierisolering, netværks- og dataseparation og, af største vigtighed for en vækstfase, et enormt skalerbarhedspotentiale.

Er Microservices svaret så?

Selvfølgelig er der ikke sådan noget som en gratis frokost. En Microservices-arkitektur har også sit eget sæt hårde udfordringer:

1) Operationel kompleksitet. DevOps-ingeniører er absolut nødvendige for at udjævne indviklingen i den nye implementeringsproces.

2) Hardware oppustet. Mikrotjenester køres ofte i Docker-containere; så snart antallet af mikrotjenester vokser, bliver det mere og mere udfordrende at køre den fulde applikation på den samme hardware som før.

3) Intercommunication overhead: hver anmodning skal muligvis interagere med en eller flere forskellige mikrotjenester gennem netværket. Dette kan medføre øget ventetid og kan være udsat for midlertidige fejl. For at implementere modstandsdygtige tjenester samt forbedre skalerbarheden i hele systemet er det nødvendigt at flytte interaktioner til asynkron besked (f.eks. Ved hjælp af Apache Kafka og / eller RabbitMQ)

4) Eventuel konsistens. Dette er sandsynligvis den sværeste udfordring ved en Microservices-arkitektur. Med en enkelt mikroservice er det muligt at oprette RDBMS-transaktioner inden for dets grænser . Desværre er dog et almindeligt problem i distribuerede arkitekturer at håndtere flere transaktioner, der ikke er inden for de samme grænser. Som et resultat kan systemet ende i en ulovlig og uoprettelig tilstand. For at afbøde sådanne problemer vedtager Conio forskellige strategier:

  1. Efter praksis med Domain Driven Design nedbrydes domænerne på højere niveau i underdomæner og begrænses til individuelt afgrænsede sammenhænge ; hver afgrænset kontekst implementeres som en mikroservice, hvor transaktionsgrænser anvendes. Dette løser muligheden for at have uoverensstemmelser for bestemte underdomæner.
  2. Implementer idempotente asynkrone interaktioner, som før eller senere løser uoverensstemmelser.
  3. Når det er muligt, undgå enhver handling, der kan involvere flere underdomæner.

5) Kompleks rapportering. Da hvert underdomæne lever inden for en bestemt afgrænset kontekst, kan komplekse rapporter, der involverer flere underdomæner, muligvis kræve forespørgsel på data fra flere datakilder: Dette kan have en negativ indvirkning både på domænes udtryk og på systemets skalerbarhed. Her i Conio har vi vedtaget en CQRS-arkitektur til at understøtte backoffice-aktivitet og forretningsanalyserapporter.

6 ) Logningssystem. Hvert element i et distribueret system bidrager til oprettelsen af ​​loggen for hele systemet. Selvom det er nødvendigt at implementere værktøjer, der kan skabe de nødvendige forbindelser mellem alle sådanne adskilte logfiler for at have en samlet log for hver interaktion. Her i Conio bruger vi ELK (ElasticSearch, Logstash, Kibana) stack til at gemme og forespørge logdata: hver log er beriget med de nødvendige korrelations-ider, der tillader ovennævnte samlet log.

Stop aldrig udviklingen

Vores synspunkt? Nedbrydning af den oprindelige enkeltkodebase skal ses som en langsigtet opgave med evigvarende forbedringer. Hos Conio tog det os et par år, hvor vi trin for trin flyttede fra 1 massiv kodebase til over 100 mikrotjenester. Vi er nået til et punkt, hvor vi føler os stolte af resultaterne, men samtidig fortsætter vi med at udforske. Der er flere mulige nye optimeringer: flytte fra Docker Swarm til Kubernetes? Migrering af backend-for-frontend-tjenester til serverløse lambda-funktioner? Skifter til en fuld kontinuerlig implementeringsoperationsflow? Mulighederne er uendelige.

Vi har berørt en række emner og teknologier her. I de næste artikler deler vi flere detaljer om vores resultater og fremskridt. Hvis du vil, er du velkommen til at kommentere og fortælle os om din oplevelse.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *