Fra monolit til microservices
Med team.blue Danmarks interne udviklingsteam.
Kan I give en kort intro af jer selv?
Selvfølgelig. Vi er team.blue Danmarks interne udviklingsteam. I team.blue har vi ansvaret for drift og udvikling af vores billing platform, vores intranet, vores kunders kontrolpaneler og vores websites. API’er, jobsystemer og integrationer til fx Hubspot og de produkter, vi sælger, står vi også for i vores team. Vi er 10 udviklere i dag. Nogle af os har været her i lang tid. Andre har først sluttet sig til teamet for nyligt.
Hvad var jeres udfordring?
Vores udfordring har været en blanding af høj vækst, øget kompleksitet og eksterne systemer/produkter.
Da vi startede i sin tid, gjorde vi det med et GIT repository, en MSSQL-database og en enkelt løsning i Visual Studio. Det var simpelt – og nemt at arbejde i, men ikke optimalt med den vækst, vi har oplevet.
På få år har vi fået markant flere .NET-projekter, vi har fået flere .NET-udviklere i teamet, og vi har fordoblet vores kundeantal.
Det begyndte at give os udfordringer.
Da vi byggede monolitten i sin tid, kunne vi sagtens overskue den, men i takt med, at vi er vokset, er det kun blevet sværere. Og da vi samtidig skulle introducere et nyt system til håndtering af domæner, var der ingen vej udenom.
Vi kunne ikke klare os med monolitten alene, så vi gik på jagt efter en anden løsning.
Hvad har løsningen været?
Efter det stod klart, at vi skulle finde en anden løsning, gik vi i gang med at undersøge mulighederne. På det tidspunkt var mange virksomheder begyndt med microservices – heriblandt Spotify.
Spotify har langt flere brugere, end vi har, men udfordringen for os har været den samme - nemlig at finde en løsning, der kan skalere, understøtte flere platforme og håndtere den komplekse forretningslogik, der er bygget ind i vores billing platform.
Første skridt for os var at oprette et microservice-miljø, hvor vi kunne deploy små ASP.NET Core Web API’er. Vi startede med en simpel Docker Swarm installation, men skiftede senere til en on-prem Kubernetes-platform.
Da først microservice-miljøet var på plads, kunne vi gøre os tanker om, hvordan vores arkitektur skulle være, og hvordan vi kunne komme i gang. I den proces fandt vi ret hurtigt ud af, at vi ikke kunne konvertere hele monolitten til microservices på én gang.
I stedet valgte vi at flytte små dele af monolitten ud til microservices.
Først flyttede vi vores e-mail kø-system. Det bruger vi til at flette parametre (som fx navne) ind i vores e-mail templates (HTML og tekst) og til at håndtere beskeder igennem et jobsystem baseret på RabbitMQ.
Flytningen gav lynhurtigt værdi for os.
Ved at isolere e-mail kø-systemet i microservices kunne vi nemmere overskue koden. Det bliver også langt nemmere at teste den, da vi bare kunne køre de enkelt jobs igen, hvis vi stødte på fejl.
Eksempel på beskeder i vores jobsystem
Det næste, vi flyttede, var det system, der håndterer vores domæner. Vi skrev det som microservices og erstattede den logik, der var i monolitten, med REST API-kald til microservices.
I dag kører monolitten – eller dele af den – stadig. Og det kommer den til i lang tid endnu. I monolitten kører vi nemlig stadig flere forretningskritiske services, hvor værdien ved at flytte dem ud ikke står til måls med andre prioriteringer.
Hver gang vi laver noget nyt i dag, er målet, at det skal være i microservices. Hvis vi skal ind og rette i monolitten, overvejer vi, om det er tiden værd at flytte koden ud. På den måde opnår vi en kontinuerlig overgang til microservices – i små skridt.
Hvilken værdi giver løsningen for kunder og kolleger?
For kunderne betyder det, at vi kan rykke hurtigere på de features, de efterspørger; at de enkelte services er mere stabile, og at vi nemmere kan skalere dem – fx ved høje loads.
For kollegerne – især vores kolleger i udviklingsafdelingen - er der næsten kun fordele med microservices.
Én af de største er, at vi bedre kan fordele ansvaret for den samlede kodebase ud på flere.
I monolitten skal du helst vide, hvordan hele koden hænger sammen. Det skal du ikke med microservices. Her er koden isoleret. Det betyder, at den er langt nemmere at overskue og teste. Det er ret fedt – især for nye udviklere. De behøver nemlig aldrig at forholde sig til hele monolitten, men kan fokusere på de microservices, de sidder med.
Er der slet ingen ulemper ved at skifte til microservices?
Jo. Selvom monolitten er kompleks, giver microservices også en kompleksitet, som du skal forholde til dig. Fx skal du finde en måde, hvorpå du kan styre dit eget miljø. Du skal også have et overblik over alle dine services og vide, præcis hvad der snakker med hvad.
Generelt set giver et distribueret system fordele, men der er også ulemper, fx hvis du arbejder med en database. I en monolit er det ofte nemt at åbne en databasetransaktion ned mod en enkelt database, men i et distribueret system risikerer du, at én handling fra brugeren kan give kald til en håndfuld microservices med et antal databaser nedenunder.
Det er også en investering. Du skal oprette nye miljøer, lave en ny CI/CD-model og definere fejlhåndtering, logning, opdatering af pakker, monitorering, osv. Stort set al struktur, vi har haft til rådighed i monolitten, har vi skulle gentænke. Det har taget tid og kommer til at tage mere tid, men indtil videre har det været umagen værd – i hvert fald for os.
Hvad har været det fedeste ved at arbejde på projektet?
Det fedeste er, at det virker. For os som udviklere er det fedt, at vores kode ligger mere isoleret, så vi nemmere kan overskue, teste og ændre den.
I dag har vi stadigt meget ældre .NET framework-kode, men langt det meste af tiden sidder vi i microservices med opdaterede NuGet-pakker, pipelines, som kører unittests og sikkerhedsscanning, og nyeste .NET 6.
Det er også ret fedt at se, hvordan vi i vores team bidrager direkte til de mål, vi har for team.blue. Skal vi vokse, skal vores kode kunne skalere, og det kan den med microservices.