{"id":35906,"date":"2019-10-31T22:07:29","date_gmt":"2019-10-31T19:07:29","guid":{"rendered":"https:\/\/prohoster.info\/blog\/perehod-ot-monolita-k-mikroservisam-istoriya-i-praktika\/"},"modified":"2019-10-31T22:07:29","modified_gmt":"2019-10-31T19:07:29","slug":"perehod-ot-monolita-k-mikroservisam-istoriya-i-praktika","status":"publish","type":"post","link":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/perehod-ot-monolita-k-mikroservisam-istoriya-i-praktika","title":{"rendered":"Overgangen fra monolit til mikrotjenester: historie og praksis","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>I denne artikel vil jeg fort\u00e6lle om, hvordan det projekt, jeg arbejder p\u00e5, har udviklet sig fra en stor monolit til et s\u00e6t af mikrotjenester.<\/p>\n<p>Projektet begyndte sin historie for mange \u00e5r siden, i begyndelsen af 2000-tallet. De f\u00f8rste versioner blev skrevet i Visual Basic 6. Med tiden blev det klart, at udviklingen i dette sprog ville blive vanskelig at underst\u00f8tte i fremtiden, da IDE'en og selve sproget udviklede sig langsomt. I slutningen af 2000'erne blev det besluttet at skifte til det mere lovende C#. Den nye version blev skrevet parallelt med forbedringerne af den gamle, og gradvist blev der brugt mere og mere .NET kode. Backend i C# var oprindeligt orienteret mod en servicearkitektur, men under udviklingen blev der anvendt f\u00e6lles biblioteker med logik, og tjenesterne blev k\u00f8rt i \u00e9n enkelt proces. Resultatet var en applikation, som vi kaldte \"service monolit\". <\/p>\n<p>En af de f\u00e5 fordele ved denne sammenkobling var muligheden for, at tjenesterne kunne kalde hinanden via et eksternt API. Der var klare foruds\u00e6tninger for at overg\u00e5 til en mere korrekt servicearkitektur, og p\u00e5 l\u00e6ngere sigt til en mikrotjenestearkitektur. <\/p>\n<p>Vi begyndte vores arbejde med dekomponering omkring 2015. Selvom vi endnu ikke har n\u00e5et den ideelle tilstand - der er stadig dele af det store projekt, som allerede er sv\u00e6re at kalde monolitter, men som heller ikke ligner mikrotjenester. Ikke desto mindre er fremskridtene betydelige. <br \/>\nOm det vil jeg fort\u00e6lle i artiklen.<\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/132bb4ea6b9dbcdd202ee090f2b86289.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>Indhold<\/h3>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"#1\"> Arkitektur og problemer med den nuv\u00e6rende l\u00f8sning<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#2\">Forventninger til mikrotjenester<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#3\">Problemer ved overgangen<\/a><\/noindex><\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"#4\">Hvordan man g\u00e5r fra monolit til mikrotjenester<\/a><\/noindex>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"#5\">Den f\u00f8rste metode<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#6\">Den anden metode<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#7\">Den tredje metode<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#8\">Den fjerde metode<\/a><\/noindex><\/li>\n<\/ul>\n<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#9\">Arbejdet med databasen<\/a><\/noindex>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"#10\">Adskillelse af eksisterende tabeller<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#11\">Adskillelse med omarbejdning<\/a><\/noindex><\/li>\n<\/ul>\n<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#12\">Arbejdet med kildekoden<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#13\">Problemer med infrastrukturen<\/a><\/noindex>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"#16\">H\u00e5ndinstallation i milj\u00f8er<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#14\">Separat logning<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#15\">Test og fejlfinding af relaterede tjenester<\/a><\/noindex><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><noindex><a rel=\"nofollow\" name=\"1\"><\/a><\/noindex><b><\/p>\n<h3>Arkitektur og problemer med den nuv\u00e6rende l\u00f8sning<\/h3>\n<p><\/b><br \/>\nDen oprindelige arkitektur s\u00e5 s\u00e5ledes ud: UI - en separat applikation, den monolitiske del var skrevet i Visual Basic 6, applikationen p\u00e5 .NET var et s\u00e6t af relaterede tjenester, der arbejdede med en ganske stor database.<\/p>\n<p><b>Ulemper ved den tidligere l\u00f8sning<\/b><\/p>\n<p><u>Enkeltpunkt for fejl<\/u><br \/>\nVi havde et enkelt fejlopunkt: applikationen p\u00e5 .NET k\u00f8rte i \u00e9n proces. Hvis der opstod en fejl i en af modulerne, fejlede hele applikationen, og vi m\u00e5tte genstarte den. Da vi automatiserer et stort antal processer for forskellige brugere, kunne alle ikke arbejde i et stykke tid p\u00e5 grund af en fejl i en af dem. Selv en programmeringsfejl hjalp backup ikke. <\/p>\n<p><u>K\u00f8 af \u00e6ndringer<\/u><br \/>\nDenne ulempe er snarere organisatorisk. I vores applikation er der mange kunder, og de \u00f8nsker alle at f\u00e5 deres \u00e6ndringer gjort s\u00e5 hurtigt som muligt. Tidligere var det umuligt at g\u00f8re dette parallelt, og alle kunderne m\u00e5tte stille sig i k\u00f8. Denne proces skabte negativitet hos forretningen, da de skulle bevise, at deres opgave havde v\u00e6rdi. Og udviklingsteamet brugte tid p\u00e5 at organisere denne k\u00f8. Det tog meget tid og kr\u00e6fter, og produktet kunne derfor ikke \u00e6ndre sig s\u00e5 hurtigt, som de \u00f8nskede.<\/p>\n<p><u>Suboptimal ressourceudnyttelse<\/u><br \/>\nN\u00e5r vi havde services i \u00e9n proces, kopierede vi altid konfigurationen fuldst\u00e6ndigt fra server til server. Vi \u00f8nskede at placere de mest belastede services separat for ikke at spilde ressourcer og for at f\u00e5 mere fleksibel kontrol over vores implementeringsskema.<\/p>\n<p><u>Sv\u00e6rt at implementere moderne teknologi<\/u><br \/>\nEt velkendt problem for alle udviklere: der er et \u00f8nske om at implementere moderne teknologi i projektet, men der er ingen mulighed. Med en stor monolitisk l\u00f8sning bliver enhver opdatering af den nuv\u00e6rende bibliotek, for ikke at n\u00e6vne overgangen til en ny, en temmelig kompleks opgave. Man skal i lang tid overbevise teamlederen om, at det vil give flere fordele end de stressede nerver. <\/p>\n<p><u>Sv\u00e6rhed ved at udgive \u00e6ndringer<\/u><br \/>\nDet var det mest alvorlige problem \u2014 vi udgav opdateringer hver anden m\u00e5ned. <br \/>\nHver opdatering blev til en rigtig katastrofe for banken, p\u00e5 trods af testning og udviklernes bestr\u00e6belser. Forretningen forstod, at de i begyndelsen af ugen ikke ville have en del af funktionaliteten til r\u00e5dighed. Udviklerne forstod, at de ville st\u00e5 over for en uge med alvorlige h\u00e6ndelser. <br \/>\nAlle \u00f8nskede at \u00e6ndre situationen. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"2\"><\/a><\/noindex><b><\/p>\n<h3>Forventninger til mikrotjenester<\/h3>\n<p><\/b><br \/>\n<u>Udgivelse af komponenter efterh\u00e5nden som de er klar. <\/u>Udgivelse af komponenter i takt med deres f\u00e6rdigg\u00f8relse takket v\u00e6re dekomponering af l\u00f8sningen og adskillelse af forskellige processer.<\/p>\n<p><u>Sm\u00e5 produktteams.<\/u> Dette er vigtigt, fordi det er sv\u00e6rt at styre et stort team, der arbejder p\u00e5 et gammelt monolitisk system. Et s\u00e5dant team bliver tvunget til at f\u00f8lge en striks proces, mens der \u00f8nskes mere kreativitet og uafh\u00e6ngighed. Det kunne kun lade sig g\u00f8re med sm\u00e5 teams.<\/p>\n<p><u>Isolering af systemer i separate processer.<\/u> Ideelt set ville vi gerne isolere i containere, men et stort antal services skrevet p\u00e5 .NET Framework k\u00f8rer kun p\u00e5 Windows. Nu dukker der services op p\u00e5 .NET Core, men de er stadig f\u00e5.<\/p>\n<p><u>Fleksibilitet i deployment.<\/u> Vi \u00f8nskede at kombinere services, som vi har behov for, i stedet for som koden tvinger os til.<\/p>\n<p><u>Brug af nye teknologier.<\/u> Dette interesserer enhver programm\u00f8r.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"3\"><\/a><\/noindex><b><\/p>\n<h3>Problemer ved overgangen<\/h3>\n<p><\/b><br \/>\nSelvf\u00f8lgelig, hvis det bare var let at dele monolitten op i mikrotjenester, ville vi ikke beh\u00f8ve at tale om det p\u00e5 konferencer og skrive artikler. Der er mange faldgruber i denne proces, og jeg vil beskrive de vigtigste, der har hindret os.<\/p>\n<p><b>Det f\u00f8rste problem<\/b> er typisk for de fleste monolitter: koblingen af forretningslogik. N\u00e5r vi skriver en monolit, \u00f8nsker vi at genbruge vores klasser for at undg\u00e5 at skrive overfl\u00f8dig kode. Men ved overgangen til mikrotjenester bliver dette et problem: al koden er temmelig stramt knyttet sammen, og det er sv\u00e6rt at adskille services.<\/p>\n<p>P\u00e5 tidspunktet for opstarten var der mere end 500 projekter i repository og over 700.000 linjer kode. Det er en temmelig stor l\u00f8sning, og <b>det andet problem<\/b>var, at det bare var umuligt at opdele det i mikrotjenester.<\/p>\n<p><b>Det tredje problem<\/b> er manglen p\u00e5 den n\u00f8dvendige infrastruktur. Faktisk arbejdede vi med manuel kopiering af kildekoden til serverne.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"4\"><\/a><\/noindex><b><\/p>\n<h3>Hvordan man g\u00e5r fra monolit til mikrotjenester<\/h3>\n<p><\/b><br \/>\n<u>Opdeling af mikrotjenester<\/u><\/p>\n<p>For det f\u00f8rste afg\u00f8r vi fra starten, at opdelingen af mikrotjenester er en iterativ proces. Vi blev altid bedt om at udvikle forretningsopgaver parallelt. Hvordan vi teknisk vil g\u00f8re dette, er allerede vores problem. Derfor forberedte vi os p\u00e5 en iterativ proces. Det vil ikke fungere anderledes, hvis du har en stor applikation, og den ikke oprindeligt er klar til at blive omskrevet.<\/p>\n<p>Hvilke metoder bruger vi til at adskille mikrotjenester?<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"5\"><\/a><\/noindex><b>Den f\u00f8rste metode <\/b>\u2014 at udskille eksisterende moduler som tjenester. I denne henseende var vi heldige: der var allerede etablerede tjenester, der arbejdede via WCF-protokollen. De var opdelt i separate assemblys. Vi flyttede dem individuelt og tilf\u00f8jede en lille opstartsmodule til hver assembly. Den blev skrevet ved hj\u00e6lp af det fantastiske bibliotek Topshelf, som g\u00f8r det muligt at k\u00f8re applikationen b\u00e5de som en tjeneste og som en konsol. Det er praktisk til fejlfinding, da der ikke kr\u00e6ves yderligere projekter i l\u00f8sningen.<\/p>\n<p>Tjenesterne var knyttet sammen gennem forretningslogik, da de brugte f\u00e6lles assemblys og arbejdede med en f\u00e6lles database. De var sv\u00e6re at kalde mikrotjenester i ren forstand. Ikke desto mindre kunne vi udgive disse tjenester separat, i forskellige processer. Dette reducerede allerede deres indflydelse p\u00e5 hinanden, hvilket mindskede problemet med parallel udvikling og en enkelt fejlpunkt.<\/p>\n<p>Assemblyen med v\u00e6rten er kun \u00e9n linje kode i Program-klassen. Vi skjulte arbejdet med Topshelf i en hj\u00e6lpeklasse.<\/p>\n<pre><code class=\"plaintext\">namespace RBA.Services.Accounts.Host\n{\n   internal class Program\n   {\n      private static void Main(string[] args)\n      {\n        HostRunner.Run(\"RBA.Services.Accounts.Host\");\n\n       }\n    }\n}\n<\/code><\/pre>\n<p>\n<noindex><a rel=\"nofollow\" name=\"6\"><\/a><\/noindex><b>Den anden metode til udskillelse af mikrotjenester:<\/b> er at oprette dem til at l\u00f8se nye opgaver. Hvis monolitten ikke vokser i den proces, er det allerede fantastisk, hvilket betyder, at vi bev\u00e6ger os i den rigtige retning. For at l\u00f8se nye opgaver fors\u00f8gte vi at lave separate tjenester. Hvis der var mulighed for det, skabte vi mere \"kanoniske\" tjenester, som fuldt ud styrer deres datamodel, med en separat database. <\/p>\n<p>Vi, ligesom mange andre, begyndte med autentifikations- og autorisationstjenester. De egner sig perfekt til dette form\u00e5l. De er uafh\u00e6ngige, og som regel har de en separat datamodel. De interagerer ikke selv med monolitten; det er kun monolitten, der henvender sig til dem for at l\u00f8se nogle opgaver. P\u00e5 disse tjenester kan vi begynde overgangen til en ny arkitektur, fejlfinde infrastrukturen, afpr\u00f8ve nogle tilgange relateret til netv\u00e6rksbiblioteker osv. I vores organisation er der ikke nogen teams, der ikke har kunnet lave en autentifikationstjeneste. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"7\"><\/a><\/noindex><b>Den tredje metode til udskillelse af mikrotjenester<\/b>, som vi bruger, er lidt specifik for os. Det handler om at flytte forretningslogik ud af UI-laget. Vores prim\u00e6re UI-applikation er desktopbaseret, og den er ligesom backend skrevet i C#. Udviklerne lavede j\u00e6vnligt fejl og placerede logik i UI, som burde have eksisteret i backend og genbruges. <\/p>\n<p>Hvis man ser p\u00e5 et konkret eksempel fra UI-koden, er det tydeligt, at en stor del af denne l\u00f8sning indeholder \u00e6gte forretningslogik, der er nyttig i andre processer, ikke kun til at opbygge UI-formularer. <\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/74c7b90ff94b343816ab3ac2fa0673c6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDer er kun reelle UI-logikker i de sidste par linjer. Vi har flyttet det til serveren for at kunne genbruge det og dermed reducere UI og opn\u00e5 den rigtige arkitektur.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"8\"><\/a><\/noindex><b>Den fjerde og vigtigste m\u00e5de at \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u044b<\/b>, som g\u00f8r det muligt at reducere monolitten, er at tr\u00e6kke eksisterende tjenester ud med omarbejdning. N\u00e5r vi tr\u00e6kker eksisterende moduler ud, som de er, kan resultatet ikke altid tilfredsstille udviklerne, og forretningsprocessen kan v\u00e6re blevet for\u00e6ldet siden funktionaliteten blev skabt. Gennem refactoring kan vi underst\u00f8tte den nye forretningsproces, fordi forretningskravene konstant \u00e6ndrer sig. Vi kan forbedre kildekoden, fjerne kendte fejl og skabe en mere kvalitetsfuld datamodel. Der opn\u00e5s mange fordele.<\/p>\n<p>Adskillelse af tjenester med omarbejdning er uadskilleligt forbundet med begrebet begr\u00e6nset kontekst. Dette er et begreb fra dom\u00e6neorienteret design. Det betyder et omr\u00e5de af dom\u00e6nemodellen, hvor alle termer i et f\u00e6lles sprog er entydigt defineret. Lad os tage et eksempel med konteksterne for forsikringer og konti. Vi har en monolitisk applikation, og vi skal arbejde med kontoen i forbindelse med forsikringer. Vi forventer, at udvikleren finder en eksisterende klasse 'Konto' i en anden samling, laver et link til den fra klassen 'Forsikring', og vi f\u00e5r fungerende kode. DRY-princippet vil blive overholdt, og opgaven vil blive udf\u00f8rt hurtigere ved at bruge eksisterende kode.<\/p>\n<p>Det viser sig, at konteksterne for regninger og forsikringer er relaterede. N\u00e5r nye krav opst\u00e5r, vil denne forbindelse forstyrre udviklingen, hvilket \u00f8ger kompleksiteten i en allerede kompleks forretningslogik. For at l\u00f8se dette problem er det n\u00f8dvendigt at finde gr\u00e6nserne mellem konteksterne i koden og fjerne deres overtr\u00e6delser. For eksempel vil forsikringskonteksten muligvis v\u00e6re tilstr\u00e6kkelig med et 20-cifret konto-nummer fra centralbanken og datoen for kontoens oprettelse. <\/p>\n<p>For at adskille disse begr\u00e6nsede kontekster fra hinanden og starte processen med at udskille mikrotjenester fra den monolitiske l\u00f8sning, anvendte vi en tilgang som at skabe eksterne API'er inde i applikationen. Hvis vi vidste, at en bestemt modul skulle blive til en mikrotjeneste, eller \u00e6ndres i behandlingen, s\u00e5 lavede vi straks opkald til logik, der tilh\u00f8rte en anden begr\u00e6nset kontekst, gennem eksterne opkald. For eksempel via REST eller WCF.<\/p>\n<p>Vi har besluttet, at vi ikke vil undg\u00e5 kode, der kr\u00e6ver at lave distribuerede transaktioner. I vores tilf\u00e6lde viste det sig at v\u00e6re ganske let at overholde denne regel. Indtil nu er der ikke opst\u00e5et situationer, hvor der virkelig er behov for h\u00e5rde distribuerede transaktioner - det er tilstr\u00e6kkeligt med den endelige konsistens mellem modulerne.<\/p>\n<p>Lad os overveje et konkret eksempel. Vi har begrebet en orkestrator - en pipeline, der behandler enheden 'anmodning'. Den skaber sekventielt en kunde, en konto og et betalingskort. Hvis kunden og kontoen er oprettet med succes, men oprettelsen af kortet mislykkes, g\u00e5r anmodningen ikke over i status 'succesfuld' og forbliver i status 'kort ikke oprettet'. I fremtiden vil baggrundsaktiviteten opsnappe den og afslutte den. Systemet er i nogen tid i en tilstand af inkonsistens, men det generelt tilfredsstiller os.<\/p>\n<p>I tilf\u00e6lde af at der faktisk opst\u00e5r en situation, hvor det bliver n\u00f8dvendigt at gemme en del af dataene konsistent, vil vi sandsynligvis g\u00e5 i retning af at konsolidere servicen for at behandle det i \u00e9n proces. <\/p>\n<p>Lad os overveje et eksempel p\u00e5 udskillelse af en mikrotjeneste. Hvordan kan vi forholdsvis sikkert bringe den til produktion? I dette eksempel har vi en separat del af systemet - modulet til l\u00f8nadministration, hvor en del af koden, vi gerne vil g\u00f8re mikrotjeneste-baseret, befinder sig.<\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/346af271b0c3f99897d330e56f713f18.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nF\u00f8rst opretter vi en mikrotjeneste ved at omskrive koden. Vi forbedrer nogle aspekter, som vi ikke var tilfredse med. Vi implementerer nye forretningskrav fra kunden. Vi tilf\u00f8jer et API Gateway i forbindelsen mellem UI og backend, som vil s\u00f8rge for at videresende opkald. <\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/bec8d68f20f3ec53af0cef225a51c2b3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDerefter frigiver vi denne konfiguration til drift, men i pilottilstand. De fleste brugere arbejder stadig med de gamle forretningsprocesser. For nye brugere udvikler vi en ny version af den monolitiske applikation, som ikke l\u00e6ngere indeholder denne proces. I praksis har vi en hybridmodel med monitoret og mikrotjenesten, der k\u00f8rer som pilot.<\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/27e98812746bb7f142fa3a3c3a03b52f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVed en vellykket pilotforl\u00f8b forst\u00e5r vi, at den nye konfiguration faktisk fungerer og kan fjerne den gamle monolit fra ligningen og lade den nye konfiguration erstatte den gamle l\u00f8sning.<\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/11dcf1d771b57d3921c0aa91b82646e1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAlt i alt benytter vi stort set alle eksisterende metoder til at opdele kildekoden fra monolitten. Alle disse metoder g\u00f8r det muligt for os at reducere st\u00f8rrelsen p\u00e5 applikationens dele og overf\u00f8re dem til nye biblioteker, hvilket skaber en mere kvalitativ kildekode.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"9\"><\/a><\/noindex><b><\/p>\n<h3>Arbejdet med databasen<\/h3>\n<p><\/b><br \/>\nVores database er sv\u00e6rere at opdele end kildekoden, da den indeholder ikke kun den nuv\u00e6rende skema, men ogs\u00e5 akkumulerede historiske data.<\/p>\n<p>Vores database, ligesom mange andre, havde en anden vigtig ulempe - dens enorme st\u00f8rrelse. Denne database blev designet i henhold til den komplekse forretningslogik i monolitten, og der er opst\u00e5et forbindelser mellem tabeller i forskellige afgr\u00e6nsede kontekster.<\/p>\n<p>I vores tilf\u00e6lde, som et endeligt problem (stor database, mange forbindelser, nogle gange uklare gr\u00e6nser mellem tabeller), opstod der et problem, der ses i mange store projekter: brugen af skabelonen shared database. Data blev hentet fra tabeller via views, gennem replikation og blev lastet op til andre systemer, hvor denne replikation var n\u00f8dvendig. Som f\u00f8lge heraf kunne vi ikke adskille tabellerne i en separat skema, fordi de blev brugt aktivt.<\/p>\n<p>I opdelingen hj\u00e6lper den n\u00e6vnte opdeling i afgr\u00e6nsede kontekster os i koden. Det giver os generelt et ret godt indtryk af, hvordan vi opdele data p\u00e5 databasens niveau. Vi forst\u00e5r, hvilke tabeller der tilh\u00f8rer en given afgr\u00e6nset kontekst, og hvilke der tilh\u00f8rer en anden.<\/p>\n<p>Vi har anvendt to globale metoder til at adskille databasen: adskillelse af eksisterende tabeller og adskillelse med omarbejdning.<\/p>\n<p>Adskillelse af eksisterende tabeller er en metode, der er god at anvende, n\u00e5r datakonstruktionen er af h\u00f8j kvalitet, opfylder forretningskravene og tilfredsstiller alle parter. I dette tilf\u00e6lde kan vi isolere de eksisterende tabeller i et separat skema.<\/p>\n<p>Adskillelse med omarbejdning er n\u00f8dvendig, n\u00e5r forretningsmodellen har \u00e6ndret sig markant, og tabellerne ikke l\u00e6ngere tilfredsstiller vores behov.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"10\"><\/a><\/noindex><b>Adskillelse af eksisterende tabeller.<\/b> Vi skal definere, hvad vi vil adskille. Uden denne viden kan vi ikke komme videre, og her kan vi f\u00e5 hj\u00e6lp fra opdeling af begr\u00e6nsede kontekster i koden. Som regel, hvis vi kan forst\u00e5 gr\u00e6nserne for kontekster i kildekoden, bliver det klart, hvilke tabeller der skal inkluderes i adskillelseslisten.<\/p>\n<p>Forestil dig, at vi har en l\u00f8sning, hvor to moduler af monolitten interagerer med \u00e9n database. Vi skal s\u00f8rge for, at kun \u00e9n modul interagerer med de adskilte tabeller, mens det andet begynder at interagere med den via API. For nu er det tilstr\u00e6kkeligt, at der kun sker skrivning gennem API'en. Dette er en n\u00f8dvendig betingelse for, at vi kan tale om mikroservices' uafh\u00e6ngighed. L\u00e6sninger kan forblive, s\u00e5 l\u00e6nge der ikke er store problemer med det.<\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/1602637ad752ac055f475cfa45d95e95.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI n\u00e6ste skridt kan vi allerede isolere den kode, der arbejder med de adskilte tabeller, med eller uden omarbejdning, i en separat mikroservice og k\u00f8re den i en separat proces eller container. Det vil v\u00e6re en selvst\u00e6ndig service med forbindelse til monolitens database og de tabeller, der ikke direkte relaterer sig til den. Monolitten interagerer stadig med den adskilte del p\u00e5 l\u00e6sesiden. <\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/36011f4e6be4f6a2f19f2f074b645dcb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSenere vil vi fjerne denne forbindelse, hvilket betyder, at l\u00e6sning af data fra monolitapplikationen fra de adskilte tabeller ogs\u00e5 vil blive overf\u00f8rt til API.<\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/290f91bbfccac2a4b384078e4cf4e337.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDern\u00e6st vil vi isolere de tabeller fra den samlede database, som kun den nye mikroservice arbejder med. Vi kan flytte tabellerne til et separat skema eller endda til en separat fysisk database. Der er stadig en l\u00e6seforbindelse mellem mikroservicen og monolitens database, men der er intet galt i det, og i denne konfiguration kan den eksistere i lang tid.<\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/ab947ac6a38ffbccd4e2b51103aef609.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDet sidste skridt er at fjerne alle forbindelser helt. I denne forbindelse kan det v\u00e6re, at vi har brug for datamigrering fra hoveddatabasen. Nogle gange \u00f8nsker vi at genbruge nogle replicerede data eller registre fra eksterne systemer i flere databaser. Dette sker periodisk hos os.<\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/f40cf17dd56b9575751e370c44f08344.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<noindex><a rel=\"nofollow\" name=\"11\"><\/a><\/noindex><b>Afdeling med omarbejdning.<\/b> Denne metode ligner meget den f\u00f8rste, blot i omvendt r\u00e6kkef\u00f8lge. Vi opretter straks en ny database og en ny mikrotjeneste, som interagerer med monolitten via API. Men der forbliver et s\u00e6t databaser, som vi p\u00e5 sigt \u00f8nsker at fjerne. Vi beh\u00f8ver det ikke l\u00e6ngere, vi har erstattet det i den nye model.<\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/c94932033e47cfa1fd56595ab9a19246.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nFor at denne ordning kan fungere, har vi sandsynligvis brug for en overgangsperiode.<\/p>\n<p>Dern\u00e6st er der to mulige tilgange.<\/p>\n<p><b>F\u00f8rste<\/b>: vi duplikerer alle data i den nye og gamle database. I dette tilf\u00e6lde opst\u00e5r der datadublering, og der kan opst\u00e5 synkroniseringsproblemer. Men vi kan tage to forskellige kunder. Den ene arbejder med den nye version, den anden med den gamle.<\/p>\n<p><b>Anden<\/b>: vi opdeler data efter et forretningskriterium. For eksempel havde vi 5 produkter i systemet, der blev opbevaret i den gamle database. Den sjette placerer vi i den nye database i forbindelse med en ny forretningsopgave. Men vi har brug for en API Gateway, der synkroniserer disse data og viser kunden, hvor og hvad de skal hente.<\/p>\n<p>Begge tilgange er anvendelige, v\u00e6lg afh\u00e6ngigt af situationen.<\/p>\n<p>N\u00e5r vi er sikre p\u00e5, at alt fungerer, kan den del af monolitten, der arbejder med de gamle database- strukturer, slukkes. <\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/973bf5015bdf49a290a5b901f89628cc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDet sidste skridt bliver at fjerne de gamle datastrukturer. <\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/fe83acc07077b7eb3717138e3c20c005.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSammenfattende kan man sige, at vi st\u00e5r over for problemer med databaserne: det er sv\u00e6rere at arbejde med dem i forhold til kildekoden, sv\u00e6rere at dele op, men det kan og skal g\u00f8res. Vi har fundet nogle metoder, der g\u00f8r det muligt at g\u00f8re det forholdsvis sikkert; det er stadig lettere at lave fejl med data end med kildekode. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"12\"><\/a><\/noindex><b><\/p>\n<h3>Arbejdet med kildekoden<\/h3>\n<p><\/b><br \/>\nS\u00e5dan s\u00e5 skemaet for kildekoden ud, da vi begyndte at analysere det monolitiske projekt.<\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/a6d886e37117ccf8f63106d6616aa653.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDen kan betragtes som opdelt i tre lag. Det er laget af k\u00f8rende moduler, plugins, tjenester og individuelle aktiviteter. Faktisk var det indgangspunkter inden for den monolitiske l\u00f8sning. Alle var fast forbundet med laget Common. Her var der forretningslogik, som blev delt af tjenesterne, samt mange forbindelser. Hver tjeneste og plugin brugte op til 10 og flere common-samlinger, afh\u00e6ngigt af deres st\u00f8rrelse og udviklernes integritet.<\/p>\n<p>Vi var heldige at have infrastrukturbiblioteker, som kunne bruges separat. <\/p>\n<p>Nogle gange opstod der situationer, hvor visse Common-objekter faktisk ikke tilh\u00f8rte dette lag, men var infrastrukturbiblioteker. Dette blev l\u00f8st ved omd\u00f8bning.<\/p>\n<p>De mest bekymrende var begr\u00e6nsede kontekster. Nogle gange blev 3-4 kontekster blandet i \u00e9n Common-samling og brugte hinanden inden for de samme forretningsfunktioner. Det var n\u00f8dvendigt at forst\u00e5, hvor de kunne opdeles, hvilke gr\u00e6nser der skulle bruges, og hvad der skulle g\u00f8res videre med mappingen af denne opdeling til kildekode-samlingerne.<\/p>\n<p>Vi formulerede nogle regler for kodeopdelingsprocessen.<\/p>\n<p><b>F\u00f8rst<\/b>: vi \u00f8nskede ikke l\u00e6ngere at dele forretningslogik mellem tjenester, aktiviteter og plugins. Vi \u00f8nskede at g\u00f8re forretningslogikken uafh\u00e6ngig inden for mikrotjenester. P\u00e5 den anden side betragtes mikrotjenester, ideelt set, som tjenester, der eksisterer fuldst\u00e6ndigt uafh\u00e6ngigt. Jeg mener, at denne tilgang er noget spild af ressourcer, og det er sv\u00e6rt at n\u00e5, da tjenester i C# alligevel vil v\u00e6re forbundet med standardbiblioteket. Vores system er skrevet i C#, og vi har ikke haft brug for at anvende andre teknologier. Derfor besluttede vi, at vi kunne tillade os at bruge f\u00e6lles tekniske samlinger. Det vigtigste er, at der ikke er nogen fragmenter af forretningslogik i dem. Hvis du har en praktisk indpakning til ORM, som du bruger, s\u00e5 er det meget dyrt at kopiere den fra tjeneste til tjeneste.<\/p>\n<p>Vores team er tilh\u00e6ngere af dom\u00e6nespecifik design, s\u00e5 \"l\u00f8garkitektur\" er en perfekt pasform for os. Grundlaget for vores tjenester blev ikke data access layer, men en samling med dom\u00e6nelogik, som kun indeholder forretningslogik og er fri for forbindelser til infrastrukturen. P\u00e5 den m\u00e5de kan vi uafh\u00e6ngigt videreudvikle dom\u00e6nesamlingen for at l\u00f8se problemer relateret til rammerne.<\/p>\n<p>P\u00e5 dette stadium st\u00f8dte vi p\u00e5 det f\u00f8rste alvorlige problem. Tjenesten skulle referere til en dom\u00e6nesamling, mens vi \u00f8nskede at g\u00f8re logikken uafh\u00e6ngig, og DRY-princippet kom os i vejen. Udviklerne \u00f8nskede at genbruge klasser fra n\u00e6rliggende samlinger for at undg\u00e5 duplicering, hvilket f\u00f8rte til, at dom\u00e6nerne igen begyndte at binde sig til hinanden. Vi analyserede resultaterne og besluttede, at problemet m\u00e5ske ogs\u00e5 l\u00e5 i strukturen af kildekoden. Vi havde et stort repository, hvor alle kilderne l\u00e5. Det var meget sv\u00e6rt at samle l\u00f8sningen for hele projektet p\u00e5 en lokal maskine. Derfor blev der oprettet separate sm\u00e5 l\u00f8sninger for dele af projektet, og ingen forhindrede os i at tilf\u00f8je en common- eller dom\u00e6nesamling og genbruge den. Det eneste v\u00e6rkt\u00f8j, der ikke tillod os dette, var kodegennemgang. Men nogle gange svigtede det ogs\u00e5.<\/p>\n<p>S\u00e5 vi begyndte at skifte til en model med separate repositories. Forretningslogikken stoppede med at flyde fra tjeneste til tjeneste, og dom\u00e6nerne blev virkelig uafh\u00e6ngige. Afgr\u00e6nsede kontekster underst\u00f8ttes mere klart. Hvordan genbruger vi de infrastrukturelle biblioteker? Vi adskilte dem i et separat repository, og derefter placerede vi dem i Nuget-pakker, som vi lagde i Artifactory. Ved enhver \u00e6ndring sker samling og offentligg\u00f8relse automatisk.<\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/8ddbc750dc7c6d397a459acf7825de90.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVores tjenester begyndte at referere til interne infrastrukturelle pakker pr\u00e6cis ligesom eksterne. Vi downloader eksterne biblioteker fra Nuget. For at arbejde med Artifactory, hvor vi lagde disse pakker, anvendte vi to pakkeh\u00e5ndteringssystemer. I sm\u00e5 repositories brugte vi ogs\u00e5 Nuget. I repositories med flere tjenester brugte vi Paket, som sikrer mere konsistens i versioner mellem moduler.<\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/672a25a70a481bff68baebe963184ccd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDer arbejdet med kildekoden, ved at \u00e6ndre arkitekturen lidt og adskille repository'er, g\u00f8r vi vores tjenester mere uafh\u00e6ngige.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"13\"><\/a><\/noindex><b><\/p>\n<h3>Problemer med infrastrukturen<\/h3>\n<p><\/b><br \/>\nDe fleste ulemper ved overgangen til mikroservices er relateret til infrastrukturen. Du vil f\u00e5 brug for automatiseret implementering og nye biblioteker til at styre infrastrukturen.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"16\"><\/a><\/noindex><b>H\u00e5ndinstallation i milj\u00f8er<\/b><\/p>\n<p>Oprindeligt installerede vi l\u00f8sningen manuelt. For at automatisere denne proces oprettede vi en CI\/CD-pipeline. Vi valgte en continuous delivery-proces, fordi continuous deployment endnu ikke er acceptabelt for os i forhold til forretningsprocesserne. Derfor sker implementeringen ved et klik, mens testen sker automatisk.<\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/0fc092326a48813398c6f3a031197bab.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVi bruger Atlassian, Bitbucket til opbevaring af kildekoder og Bamboo til bygninger. Vi kan lide at skrive build-scripts i Cake, fordi det er det samme som C#. I Artifactory kommer klar pakkede versioner, og Ansible overf\u00f8rer automatisk til testserverne, hvorefter de kan testes med det samme.<\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/fcc743cfaa4a24b906ceeb40ec1ba0a0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<noindex><a rel=\"nofollow\" name=\"14\"><\/a><\/noindex><b><\/p>\n<h3>Separat logning<\/h3>\n<p><\/b><br \/>\nEngang var en af id\u00e9erne ved monolitten at sikre f\u00e6lles logning. Vi skulle ogs\u00e5 finde ud af, hvad vi skulle g\u00f8re med de enkelte logs, der ligger p\u00e5 diske. Logs skrives til tekstfiler. Vi besluttede at bruge det standard ELK-stack. Vi valgte ikke at skrive direkte til ELK gennem udbyderne, men besluttede, at vi ville forbedre tekstlogs og registrere sporings-ID'er som identifikatorer, ved at tilf\u00f8je tjenestens navn, s\u00e5 vi senere kunne analysere disse logs.<\/p>\n<p><img decoding=\"async\" alt=\"Overgangen fra monolit til mikrotjenester: historie og praksis\" src=\"\/wp-content\/uploads\/2019\/07\/8e58c66ac134e65abe34b59939f31483.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVed hj\u00e6lp af Filebeat f\u00e5r vi mulighed for at indsamle vores logs fra <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/da\/server\/\"   title=\"servere\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"1338\">servere<\/a>, og derefter konvertere dem, bruge Kibana til at opbygge foresp\u00f8rgsler i UI og se, hvordan kaldet skete mellem tjenesterne. Dette hj\u00e6lper meget med sporings-ID'et.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"15\"><\/a><\/noindex><b><\/p>\n<h3>Test og fejlfinding af relaterede tjenester<\/h3>\n<p><\/b><br \/>\nOprindeligt forstod vi ikke helt, hvordan vi skulle debugge de udviklede tjenester. Det var simpelt med monolitten, vi k\u00f8rte den p\u00e5 den lokale maskine. Vi fors\u00f8gte f\u00f8rst ogs\u00e5 at g\u00f8re det med mikrotjenester, men nogle gange kr\u00e6ver en fuldst\u00e6ndig lancering af en mikrotjeneste, at flere andre ogs\u00e5 startes, hvilket er lidt besv\u00e6rligt. Vi inds\u00e5, at vi var n\u00f8dt til at skifte til en model, hvor vi kun efterlader den tjeneste eller de tjenester, vi vil debugge, p\u00e5 den lokale maskine. Resten af tjenesterne bruges fra servere, der matcher konfigurationen med produktion. Efter debugging, ved testning, udleveres kun de \u00e6ndrede tjenester til testserveren for hver opgave. P\u00e5 den m\u00e5de testes l\u00f8sningen i den form, som den i fremtiden vil v\u00e6re i produktion.<\/p>\n<p>Der er servere, hvor kun produktionsversionerne af tjenesterne er installeret. Disse servere er n\u00f8dvendige i tilf\u00e6lde af h\u00e6ndelser, til kontrol af leverancer f\u00f8r deployment og til intern tr\u00e6ning.<\/p>\n<p>Vi har introduceret en proces for automatisk testning ved hj\u00e6lp af det popul\u00e6re bibliotek Specflow. Tests udf\u00f8res automatisk med NUnit lige efter implementeringen fra Ansible. Hvis d\u00e6kningen for en opgave er helt automatisk, er der ikke behov for manuel testning. Selvom der nogle gange stadig kr\u00e6ves yderligere manuel testning. For at bestemme, hvilke tests der skal k\u00f8res for en given opgave, bruger vi tags i Jira.<\/p>\n<p>Derudover er behovet for belastningstestning steget; det blev tidligere kun udf\u00f8rt sj\u00e6ldent. Til at k\u00f8re testene bruger vi JMeter, til opbevaring InfluxDB, og til at opbygge grafer over processen Grafana.<\/p>\n<p><b><\/p>\n<h3>Hvad har vi opn\u00e5et?<\/h3>\n<p><\/b><br \/>\nFor det f\u00f8rste har vi fjernet begrebet 'release'. Der er ikke l\u00e6ngere to-m\u00e5neders kolossale releases, hvor denne kolos blev implementeret i produktionsmilj\u00f8et og midlertidigt br\u00f8d forretningsprocesserne. Nu implementerer vi tjenester i gennemsnit hver 1,5 dag, grupperet, fordi de tr\u00e6der i kraft efter godkendelse.<\/p>\n<p>I vores system er der ingen fatale fejl. Hvis vi udgiver en mikrotjeneste med en fejl, vil den tilknyttede funktionalitet v\u00e6re brudt, mens al anden funktionalitet ikke vil blive p\u00e5virket. Dette forbedrer brugeroplevelsen betydeligt.<\/p>\n<p>Vi kan styre implementeringsskemaet. Det er muligt at adskille grupper af tjenester fra resten af l\u00f8sningen, hvis der er behov for det.<\/p>\n<p>Derudover har vi betydeligt minimeret problemet med lange ventelister til forbedringer. Vi har f\u00e5et separate produktteams, der arbejder med nogle af tjenesterne uafh\u00e6ngigt. Her passer Scrum-processen godt. Et konkret team kan have en separat produktejer, som s\u00e6tter opgaver for dem. <\/p>\n<p><b><\/p>\n<h3>CV<\/h3>\n<p><\/b><\/p>\n<ul>\n<li>Mikrotjenester er velegnede til dekomponering af komplekse systemer. I processen begynder vi at forst\u00e5, hvad der findes i vores system, hvilke begr\u00e6nsede kontekster der er, hvor deres gr\u00e6nser ligger. Dette g\u00f8r det muligt at fordele forbedringer korrekt blandt modulerne og undg\u00e5 kodeforvirring. <\/li>\n<li>Mikrotjenester giver organisatoriske fordele. De omtales ofte kun som en arkitektur, men enhver arkitektur er n\u00f8dvendig for at im\u00f8dekomme forretningsbehov, ikke af sig selv. Derfor kan vi sige, at mikrotjenester er velegnede til at l\u00f8se opgaver med sm\u00e5 teams, is\u00e6r nu hvor Scrum er meget popul\u00e6rt.<\/li>\n<li>Adskillelse er en iterativ proces. Man kan ikke tage en applikation og simpelthen opdele den i mikrotjenester. Det resulterende produkt vil n\u00e6ppe v\u00e6re funktionelt. Ved at opdele mikrotjenester er det fordelagtigt at omskrive eksisterende legacy, dvs. at omdanne det til kode, som vi kan lide, og som bedre opfylder forretningens krav til funktionalitet og hastighed.\n<p><i>En lille advarsel:<\/i> omkostningerne ved at overg\u00e5 til mikrotjenester er betydelige. Der gik meget tid p\u00e5 at l\u00f8se infrastrukturproblemet. S\u00e5 hvis du har en lille applikation, der ikke kr\u00e6ver specifik skalering, hvis der ikke er mange kunder, der k\u00e6mper om opm\u00e6rksomheden og tiden fra dit team, s\u00e5 er mikrotjenester m\u00e5ske ikke det, du har brug for i dag. Det er ret dyrt. Hvis man starter processen med mikrotjenester, vil omkostningerne i starten v\u00e6re h\u00f8jere end hvis det samme projekt startes med udviklingen af et monolit. <\/p>\n<p>P.S. En mere f\u00f8lelsesladet fort\u00e6lling (som om det var personligt til dig) \u2013 ved <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=qTNbx18DzpQ\">linket<\/a><\/noindex>. <br \/>\nHer er den fulde version af rapporten.<\/li>\n<\/ul>\n<p>Kilde: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/raiffeisenbank\/blog\/458404\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043f\u0440\u043e\u0435\u043a\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e, \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u043b\u0441\u044f \u0438\u0437 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u0430 \u0432 \u043d\u0430\u0431\u043e\u0440 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430\u0447\u0430\u043b \u0441\u0432\u043e\u044e \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u0430\u0432\u043d\u043e, \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 2000. \u041f\u0435\u0440\u0432\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u0431\u044b\u043b\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u043d\u0430 Visual Basic 6. \u0421 \u0442\u0435\u0447\u0435\u043d\u0438\u0435\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0442\u0430\u043b\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043d\u0430 \u044d\u0442\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c, \u0442\u0430\u043a \u043a\u0430\u043a IDE [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":26858,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-35906","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043f\u0440\u043e\u0435\u043a\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e, \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u043b\u0441\u044f \u0438\u0437 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u0430 \u0432 \u043d\u0430\u0431\u043e\u0440 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430\u0447\u0430\u043b \u0441\u0432\u043e\u044e \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u0430\u0432\u043d\u043e, \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 2000.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/perehod-ot-monolita-k-mikroservisam-istoriya-i-praktika\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043e\u0442 \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u0430 \u043a \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c: \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043f\u0440\u043e\u0435\u043a\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e, \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u043b\u0441\u044f \u0438\u0437 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u0430 \u0432 \u043d\u0430\u0431\u043e\u0440 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430\u0447\u0430\u043b \u0441\u0432\u043e\u044e \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u0430\u0432\u043d\u043e, \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 2000.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/perehod-ot-monolita-k-mikroservisam-istoriya-i-praktika\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:07:29+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:07:29+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Overgangen fra monolit til mikrotjenester: historie og praksis | ProHoster","description":"I denne artikel vil jeg fort\u00e6lle om, hvordan det projekt, jeg arbejder p\u00e5, blev omdannet fra en stor monolit til et s\u00e6t mikrotjenester. Projektet begyndte sin historie for l\u00e6nge siden, i begyndelsen af 2000'erne.","canonical_url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/perehod-ot-monolita-k-mikroservisam-istoriya-i-praktika","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"da_DK","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043e\u0442 \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u0430 \u043a \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c: \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 | ProHoster","og:description":"\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043f\u0440\u043e\u0435\u043a\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e, \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u043b\u0441\u044f \u0438\u0437 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u0430 \u0432 \u043d\u0430\u0431\u043e\u0440 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430\u0447\u0430\u043b \u0441\u0432\u043e\u044e \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u0430\u0432\u043d\u043e, \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 2000.","og:url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/perehod-ot-monolita-k-mikroservisam-istoriya-i-praktika","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:07:29+00:00","article:modified_time":"2019-10-31T19:07:29+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"35906","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-02-09 17:04:56","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:54:38","updated":"2026-02-09 17:04:56","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/35906","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/comments?post=35906"}],"version-history":[{"count":1,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/35906\/revisions"}],"predecessor-version":[{"id":158582,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/35906\/revisions\/158582"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media\/26858"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=35906"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=35906"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=35906"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}