{"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\/hr\/blog\/administrirovanie\/perehod-ot-monolita-k-mikroservisam-istoriya-i-praktika","title":{"rendered":"Prijelaz s monolita na mikroservise: povijest i praksa","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>U ovom \u010dlanku \u0107u govoriti o tome kako se projekt na kojem radim pretvorio iz velike monolite u skup mikroservisa.<\/p>\n<p>Projekt je zapo\u010deo svoju povijest davno, po\u010detkom 2000-ih. Prve verzije napisane su u Visual Basic 6. S vremenom je postalo jasno da \u0107e razvoj na ovom jeziku biti te\u0161ko odr\u017eavati, jer se IDE i sam jezik slabo razvijaju. Krajem 2000-ih odlu\u010deno je prelazak na perspektivniji C#. Nova verzija se pisala paralelno s doradom stare, a postepeno je sve vi\u0161e koda bilo na .NET. Backend na C# je prvotno bio orijentiran na servisnu arhitekturu, ali su se prilikom razvoja koristile zajedni\u010dke biblioteke s logikom, a servisi su se pokretali u jedinstvenom procesu. Tako je nastala aplikacija koju smo nazivali \"servisni monolit\". <\/p>\n<p>Jedna od rijetkih prednosti takve povezanosti bila je mogu\u0107nost da servisi pozivaju jedni druge preko vanjskog API-ja. Postojale su jasne pretpostavke za prelazak na ispravniju servisnu, a u budu\u0107nosti i mikroservisnu arhitekturu. <\/p>\n<p>Svoj posao na dekompoziciji zapo\u010deli smo otprilike 2015. godine. Iako jo\u0161 nismo postigli idealno stanje - ostali su dijelovi velikog projekta koje je ve\u0107 te\u0161ko nazvati monolitima, ali ni na mikroservise ne izgledaju. Unato\u010d tome, napredak je zna\u010dajan. <br \/>\nO tome \u0107u pisati u \u010dlanku.<\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" 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>Sadr\u017eaj<\/h3>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"#1\"> Arhitektura i problemi postoje\u0107eg rje\u0161enja<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#2\">O\u010dekivanja od mikroservisa<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#3\">Problemi prelaska<\/a><\/noindex><\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"#4\">Kako pre\u0107i od monolita do mikroservisa<\/a><\/noindex>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"#5\">Prvi na\u010din<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#6\">Drugi na\u010din<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#7\">Tre\u0107i na\u010din<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#8\">\u010cetvrti na\u010din<\/a><\/noindex><\/li>\n<\/ul>\n<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#9\">Rad s BDD-om<\/a><\/noindex>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"#10\">Odvajanje postoje\u0107ih tablica<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#11\">Odvajanje s preradom<\/a><\/noindex><\/li>\n<\/ul>\n<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#12\">Rad s izvorni kodom<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#13\">Problemi infrastrukture<\/a><\/noindex>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"#16\">Ru\u010dno postavljanje u okru\u017eenja<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#14\">Odvojeno logiranje<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#15\">Testiranje i debagiranje povezanih servisa<\/a><\/noindex><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><noindex><a rel=\"nofollow\" name=\"1\"><\/a><\/noindex><b><\/p>\n<h3>Arhitektura i problemi postoje\u0107eg rje\u0161enja<\/h3>\n<p><\/b><br \/>\nPrvotna arhitektura izgledala je ovako: UI \u2014 odvojena aplikacija, monolitni dio napisan u Visual Basic 6, aplikacija na .NET predstavljala je niz povezanih servisa koji rade s dovoljno velikom bazom podataka.<\/p>\n<p><b>Nedostaci prija\u0161njeg rje\u0161enja<\/b><\/p>\n<p><u>Jedinstvena ta\u010dka gre\u0161ke<\/u><br \/>\nImali smo jedinstvenu ta\u010dku otkaza: aplikacija na .NET je radila u jednom procesu. Ako bi do\u0161lo do kvara u bilo kojem od modula, cela aplikacija bi se sru\u0161ila i morali bismo je ponovo pokrenuti. Kako automatizujemo veliki broj procesa za razli\u010dite korisnike, usled kvara u jednom od njih, svi su na neko vreme prestali raditi. \u010cak ni rezervisanje nije pomoglo kod programskih gre\u0161aka. <\/p>\n<p><u>Lista promjena<\/u><br \/>\nOva nijansa je prete\u017eno organizacijska. U na\u0161oj aplikaciji postoji mnogo korisnika, i svi \u017eele da je nadograde \u0161to je br\u017ee mogu\u0107e. Ranije je bilo nemogu\u0107e uraditi to istovremeno, pa su se svi korisnici povla\u010dili u red. Ovaj proces izazivao je negativne reakcije u poslovanju, jer su morali dokazivati da njihovi zahtevi imaju vrednost. Razvojni tim je tro\u0161io vreme na organizaciju tog reda. To je oduzimalo mnogo vremena i resursa, a proizvod nije mogao da se menja onako brzo kako su to \u017eeleli.<\/p>\n<p><u>Neoptimalno kori\u0161\u0107enje resursa<\/u><br \/>\nPrilikom postavljanja servisa u jedinstvenom procesu, uvek smo u potpunosti kopirali konfiguraciju sa servera na server. \u017deleli smo da postavimo najoptere\u0107enije servise odvojeno, kako bismo izbegli prokletstvo resursa i dobili fleksibilniju kontrolu nad na\u0161om razvojnom \u0161emom.<\/p>\n<p><u>Te\u017eak unos modernih tehnologija<\/u><br \/>\nPoznata svima problematika me\u0111u programerima: postoji \u017eelja da se u projekt unesu moderne tehnologije, ali nema mogu\u0107nosti. U velikim monolitnim re\u0161enjima, svaka nadogradnja trenutne biblioteke, ne govorimo o prelazu na novu, postaje poprili\u010dno slo\u017eena stvar. Potrebno je dugo ube\u0111ivati tim lidera da \u0107e doneti vi\u0161e benefita nego \u0161to \u0107e biti potro\u0161eno nerava. <\/p>\n<p><u>Slo\u017eenost isporuke promena<\/u><br \/>\nOvo je bio najte\u017ei problem \u2013 imali smo izdanja svaka dva meseca. <br \/>\nSvako izdanje je postajalo prava katastrofa za banku, uprkos testiranju i naporima programera. Poslovanje je shvatilo da na po\u010detku nedelje ne\u0107e raditi deo funkcionalnosti. A programeri su znali da ih \u010deka nedelja ozbiljnih incidenata. <br \/>\nSvi su \u017eeleli da promene situaciju. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"2\"><\/a><\/noindex><b><\/p>\n<h3>O\u010dekivanja od mikroservisa<\/h3>\n<p><\/b><br \/>\n<u>Isporuka komponenti prema spremnosti. <\/u>Isporuka komponenti prema spremnosti zahvaljuju\u0107i dekompoziciji re\u0161enja i odvojenim procesima.<\/p>\n<p><u>Mali produktni timovi.<\/u> To je va\u017eno jer je s velikim timom koji radi na starom monolitu te\u0161ko upravljati. Takav tim bio je primoran raditi po strogom postupku, dok su \u017eeljeli vi\u0161e kreativnosti i neovisnosti. To su si mogli priu\u0161titi samo mali timovi.<\/p>\n<p><u>Izolacija servisa u zasebnim procesima.<\/u> Idealan bi scenarij bio izolirati servise u kontejnerima, ali velik broj servisa napisanih na .NET Frameworku radi samo na Windowsu. Posljednjih se godina pojavljuju servisi na .NET Core, ali ih jo\u0161 uvijek nema mnogo.<\/p>\n<p><u>Fleksibilnost implementacije.<\/u> \u017deljeli bismo kombinirati servise onako kako mi to \u017eelimo, a ne kako kod to zahtijeva.<\/p>\n<p><u>Kori\u0161tenje novih tehnologija.<\/u> To je zanimljivo svakom programeru.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"3\"><\/a><\/noindex><b><\/p>\n<h3>Problemi prelaska<\/h3>\n<p><\/b><br \/>\nNaravno, ako bi bilo lako razbiti monolit na mikrosservise, o tome se ne bi govorilo na konferencijama i pisale bi se \u010dlanke. U ovom procesu ima mnogo zamki, opisat \u0107u glavne koje su nam pravile probleme.<\/p>\n<p><b>Prvi problem<\/b> tipi\u010dno za ve\u0107inu monolita: povezanost poslovne logike. Kada pi\u0161emo monolit, \u017eelimo ponovo koristiti na\u0161e klase kako bismo izbjegli suvi\u0161an kod. Prijelazom na mikrosservise to postaje problem: sav kod je dovoljno \u010dvrsto povezan i te\u0161ko je odvojiti servise.<\/p>\n<p>U trenutku po\u010detka rada u repozitoriju je bilo vi\u0161e od 500 projekata i vi\u0161e od 700 tisu\u0107a linija koda. To je prili\u010dno veliko rje\u0161enje i <b>drugi problem<\/b>. Jednostavno je bilo nemogu\u0107e uzeti i podijeliti ga na mikrosservise.<\/p>\n<p><b>Tre\u0107i problem<\/b> \u2014 nedostatak potrebne infrastrukture. U su\u0161tini, bavili smo se ru\u010dnim kopiranjem izvornih kodova na servere.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"4\"><\/a><\/noindex><b><\/p>\n<h3>Kako pre\u0107i od monolita do mikroservisa<\/h3>\n<p><\/b><br \/>\n<u>Izdvajanje mikrosservisa<\/u><\/p>\n<p>Prvo, odmah smo sebi odredili da je razdvajanje mikrosservisa iterativan proces. Uvijek su od nas tra\u017eili da istovremeno radimo na razvoju poslovnih zadataka. Kako \u0107emo to tehni\u010dki realizirati \u2014 to je ve\u0107 na\u0161 problem. Stoga smo se pripremali za iterativni proces. Na drugi na\u010din ne mo\u017ee kada imate veliku aplikaciju koja nije prvotno pripremljena za prepisivanje.<\/p>\n<p>Koje na\u010dine koristimo za izdvajanje mikrosservisa?<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"5\"><\/a><\/noindex><b>Prvi na\u010din <\/b>\u2014 izdvajanje postoje\u0107ih modula kao usluga. U tom pogledu smo imali sre\u0107e: ve\u0107 su postojale usluge koje su radile na WCF protokolu. Bile su raspore\u0111ene u zasebnim paketima. Premje\u0161tali smo ih odvojeno, dodaju\u0107i maleni pokreta\u010dki modul svakom paketu. Napravljen je uz pomo\u0107 sjajne biblioteke Topshelf, koja omogu\u0107ava pokretanje aplikacije kao usluge ili kao konzolnog programa. Ovo je prakti\u010dno za otklanjanje gre\u0161aka, jer nije potrebno dodatne projekte unutar rje\u0161enja.<\/p>\n<p>Usluge su bile povezane poslovnom logikom, jer su koristile zajedni\u010dke pakete i radile s zajedni\u010dkom bazom podataka. Te\u0161ko ih je bilo nazvati \u010distim mikrouslu\u017ebama. Ipak, mogli smo te usluge izdavati odvojeno, u razli\u010ditim procesima. To je ve\u0107 smanjilo utjecaj jednih na druge, smanjuju\u0107i problem paralelne izrade i jedinstvene ta\u010dke kvara.<\/p>\n<p>Paketa s hostom je samo jedna linija koda u klasi Program. Rad s Topshelf-om smo sakrili u pomo\u0107nu klasu.<\/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>Drugi na\u010din izdvajanja mikrouslu\u017ebi:<\/b> izraditi ih za rje\u0161avanje novih zadataka. Ako pritom monolit ne raste, to je ve\u0107 odli\u010dno, zna\u010di da idemo u pravom smjeru. Za rje\u0161avanje novih zadataka nastojali smo praviti posebne usluge. Ako je bila mogu\u0107nost, stvarali smo usluge koje su \u201ekanoni\u010dne\u201c, \u0161to potpuno upravljaju svojim modelom podataka, odvojenom bazom podataka. <\/p>\n<p>Mi, kao i mnogi, po\u010deli smo s uslugama za autentifikaciju i autorizaciju. One su savr\u0161ene za to. Nezavisne su, obi\u010dno imaju odvojen model podataka. Same ne komuniciraju s monolitom, ve\u0107 se on obra\u0107a njima za rje\u0161avanje odre\u0111enih zadataka. Na ovim uslugama mo\u017eemo zapo\u010deti prijelaz na novu arhitekturu, testirati infrastrukturu, isprobati neke pristupe povezane s mre\u017enim bibliotekama itd. U na\u0161oj organizaciji nema timova koji ne bi uspjeli napraviti uslugu autentifikacije. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"7\"><\/a><\/noindex><b>Tre\u0107i na\u010din izdvajanja mikrouslu\u017ebi<\/b>, koji koristimo, pomalo je specifi\u010dan za nas. To je izdvajanje poslovne logike iz UI sloja. Na\u0161a glavna UI aplikacija je desktop aplikacija, koja je, kao i backend, napisana u C#. Programeri povremeno grije\u0161e i iznose na UI dijelove logike koji bi trebali postojati u backendu i ponovo se koristiti. <\/p>\n<p>Ako pogledamo stvarni primjer iz koda UI dijela, jasno je da ve\u0107i dio ovog rje\u0161enja sadr\u017ei pravu poslovnu logiku, koja je korisna u drugim procesima, ne samo za izgradnju UI obrasca. <\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" src=\"\/wp-content\/uploads\/2019\/07\/74c7b90ff94b343816ab3ac2fa0673c6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nStvarne logike UI tu je samo posljednjih nekoliko redaka. Premjestili smo je na server kako bismo omogu\u0107ili ponovnu upotrebu, smanjuju\u0107i tako UI i posti\u017eu\u0107i ispravnu arhitekturu.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"8\"><\/a><\/noindex><b>\u010cetvrti, najva\u017eniji na\u010din izdvajanja mikroservisa<\/b>, koji tako\u0111er omogu\u0107ava smanjenje monolita, jeste izdvajanje postoje\u0107ih servisa s preradom. Kada postoje\u0107e module izdvojimo onakve kakvi jesu, rezultat ne svi\u0111a uvijek programerima, a poslovni proces od vremena stvaranja funkcionalnosti mogao je zastarjeti. Zahvaljuju\u0107i refaktoringu, mo\u017eemo podr\u017eati novi poslovni proces, jer se zahtjevi poslovanja neprestano mijenjaju. Mo\u017eemo pobolj\u0161ati izvorni kod, ukloniti poznate defekte, stvoriti kvalitetniji model podataka. Prikuplja se mnogo prednosti.<\/p>\n<p>Izdvajanje servisa s preradom neodvojivo je povezano s pojmom ograni\u010denog konteksta. Ovaj pojam dolazi iz predmetno-orijentiranog projektiranja. Zna\u010di odjeljak domenne modela, u kojem su svi pojmovi jedinstvenog jezika jednozna\u010dno definirani. Razmotrimo primjer konteksta osiguranja i ra\u010duna. Imamo monolitnu aplikaciju i potrebno je raditi sa ra\u010duna u osiguranju. O\u010dekujemo da \u0107e programer prona\u0107i u drugoj biblioteci postoje\u0107u klasu \u201eRa\u010dun\u201c, napraviti referencu na nju iz klase \u201eOsiguranje\u201c, i dobit \u0107emo funkcionalni kod. Princip DRY bit \u0107e po\u0161tovan, zadatak \u0107e se uz pomo\u0107 postoje\u0107eg koda br\u017ee realizirati.<\/p>\n<p>Na kraju se pokazuje da su kontekst ra\u010duna i osiguranja povezani. Kada se pojave novi zahtjevi, ova veza \u0107e ometati razvoj, pove\u0107avaju\u0107i slo\u017eenost i onako slo\u017eene poslovne logike. Da bismo rije\u0161ili ovaj problem, potrebno je u kodu prona\u0107i granice izme\u0111u konteksta i ukloniti njihova kr\u0161enja. Na primjer, kontekstu osiguranja, sasvim je mogu\u0107e, bit \u0107e dovoljan 20-znamenkasti broj ra\u010duna HNB-a i datum otvaranja ra\u010duna. <\/p>\n<p>Kako bismo odvojili te ograni\u010dene kontekste jedne od drugih i zapo\u010deli proces izdvajanja mikroservisa iz monolitnog rje\u0161enja, koristili smo pristup stvaranja vanjskih API-ja unutar aplikacije. Ako smo znali da neki modul treba postati mikroservis, kako bi se promijenio u okviru procesa, odmah smo radili pozive logike koja pripada drugom ograni\u010denom kontekstu, kroz vanjske pozive. Na primjer, putem REST-a ili WCF-a.<\/p>\n<p>\u010cvrsto smo odlu\u010dili da ne\u0107emo izbjegavati kod koji zahtijeva obavljanje distribuiranih transakcija. U na\u0161em slu\u010daju pokazalo se dovoljno lako pridr\u017eavati se ove pravilnosti. Do sada nismo nai\u0161li na situacije kada su stvarno potrebne stroge distribuirane transakcije \u2014 sasvim je dovoljno kona\u010dno uskla\u0111ivanje izme\u0111u modula.<\/p>\n<p>Razmotrimo konkretan primjer. Imamo pojam orkestratora \u2014 cijevi koja obra\u0111uje entitet 'zahtjeva'. Redom stvara klijenta, ra\u010dun i bankovnu karticu. Ako su klijent i ra\u010dun uspje\u0161no kreirani, a kreiranje kartice nije uspjelo, zahtjev ne prelazi u status 'uspje\u0161no' i ostaje u statusu 'kartica nije kreirana'. U budu\u0107nosti \u0107e pozadinska aktivnost pokupiti to i zavr\u0161iti. Sustav je neko vrijeme u stanju nesuglasnosti, ali nas to, u cijelosti, zadovoljava.<\/p>\n<p>U slu\u010daju da se pojavi situacija kada \u0107e biti potrebno uskla\u0111eno sa\u010duvati dio podataka, vjerojatno \u0107emo oti\u0107i na pove\u0107anje servisa kako bismo obradili to u jednom procesu. <\/p>\n<p>Razmotrimo primjer izdvajanja mikroservisa. Na koji na\u010din se mo\u017ee relativno sigurno dovesti do produkcije? U ovom primjeru imamo poseban dio sustava \u2014 modul obra\u010duna pla\u0107a, jedan od dijelova koda koji bismo \u017eeljeli u\u010diniti mikroservisnim.<\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" src=\"\/wp-content\/uploads\/2019\/07\/346af271b0c3f99897d330e56f713f18.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPrvo kreiramo mikroservis, prepisuju\u0107i kod. Pobolj\u0161avamo odre\u0111ene aspekte koji nam nisu odgovarali. Provodimo nove poslovne zahtjeve od klijenta. Dodajemo API Gateway u vezu izme\u0111u UI-a i backend-a, koji \u0107e omogu\u0107iti proslje\u0111ivanje poziva. <\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" src=\"\/wp-content\/uploads\/2019\/07\/bec8d68f20f3ec53af0cef225a51c2b3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nZatim ovu konfiguraciju pu\u0161tamo u pogon, ali u pilot stanju. Ve\u0107ina na\u0161ih korisnika i dalje koristi stare poslovne procese. Za nove korisnike razvijamo novu verziju monolitne aplikacije koja vi\u0161e ne uklju\u010duje taj proces. U su\u0161tini, imamo vezu monolita i mikroservisa koja radi kao pilot.<\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" src=\"\/wp-content\/uploads\/2019\/07\/27e98812746bb7f142fa3a3c3a03b52f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAko imamo uspje\u0161an pilot, shva\u0107amo da nova konfiguracija doista radi i mo\u017eemo ukloniti stari monolit te ostaviti novu konfiguraciju umjesto starog rje\u0161enja.<\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" src=\"\/wp-content\/uploads\/2019\/07\/11dcf1d771b57d3921c0aa91b82646e1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDakle, koristimo gotovo sve postoje\u0107e metode za razdvajanje izvornog koda monolita. Sve one nam omogu\u0107uju smanjivanje veli\u010dine dijelova aplikacije i prijenos na nove biblioteke, \u010dine\u0107i izvorni kod kvalitetnijim.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"9\"><\/a><\/noindex><b><\/p>\n<h3>Rad s BDD-om<\/h3>\n<p><\/b><br \/>\nBaza podataka se te\u017ee razdvaja nego izvorni kod, jer sadr\u017ei ne samo trenutnu shemu, ve\u0107 i akumulirane povijesne podatke.<\/p>\n<p>Na\u0161a baza podataka, kao i mnoge druge, imala je jo\u0161 jedan va\u017ean nedostatak \u2014 ogroman je veli\u010dinu. Ova baza podataka projektirana je prema slo\u017eenoj poslovnoj logici monolita, a izme\u0111u tablica razli\u010ditih ograni\u010denih konteksta nastale su veze.<\/p>\n<p>U na\u0161em slu\u010daju, na kraju svih nevolja (velika baza podataka, brojne veze, ponekad nejasne granice izme\u0111u tablica) pojavila se problematika koja se susre\u0107e u mnogim velikim projektima: kori\u0161tenje \u0161ablona shared database. Podaci su uzimani iz tablica preko view-a, replicirani i isporu\u010divani u druge sustave gdje su bila potrebna ta replikacija. Kao rezultat toga, nismo mogli izdvojiti tablice u zasebnu shemu, jer su bile aktivno kori\u0161tene.<\/p>\n<p>U razdvajanju nam poma\u017ee to isto razdvajanje na ograni\u010dene kontekste u kodu. Obi\u010dno nam daje dovoljno dobar uvid u to kako razbijamo podatke na razini baze podataka. Razumijemo koje tablice pripadaju jednom ograni\u010denom kontekstu, a koje drugom.<\/p>\n<p>Primijenili smo dva globalna na\u010dina odvajanja baze podataka: odvajanje postoje\u0107ih tablica i odvajanje s preradom.<\/p>\n<p>Odvajanje postoje\u0107ih tablica je metoda koja se dobro primjenjuje kada je struktura podataka kvalitetna, zadovoljava poslovne zahtjeve i svima odgovara. U tom slu\u010daju mo\u017eemo izdvojiti postoje\u0107e tablice u zasebnu shemu.<\/p>\n<p>Odvajanje s preradom je potrebno kada se poslovni model zna\u010dajno promijenio, a tablice vi\u0161e ne zadovoljavaju na\u0161e potrebe.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"10\"><\/a><\/noindex><b>Odvajanje postoje\u0107ih tablica.<\/b> Moramo odrediti \u0161to \u0107emo odvajati. Bez tog znanja ni\u0161ta ne\u0107e funkcionirati, a ovdje nam mo\u017ee pomo\u0107i odvajanje ograni\u010denih konteksta u kodu. Obi\u010dno, ako uspijemo shvatiti granice konteksta u izvornoj kodu, postaje jasno koje tablice trebaju biti na popisu za odvajanje.<\/p>\n<p>Zamislimo da imamo rje\u0161enje u kojem dva modula monolita komuniciraju s jednom bazom podataka. Moramo osigurati da samo jedan modul komunicira s dijelom odvojenih tablica, a drugi neka zapo\u010dne komunikaciju s njom preko API-ja. U po\u010detku je dovoljno da se preko API-ja vr\u0161i samo upis. Ovo je preduvjet da bismo mogli govoriti o neovisnosti mikroslu\u017ebi. Veze za \u010ditanje mogu ostati, dok u tome nema velikih problema.<\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" src=\"\/wp-content\/uploads\/2019\/07\/1602637ad752ac055f475cfa45d95e95.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSljede\u0107i korak je da dio koda koji radi s odvojenim tablicama, s preradom ili bez nje, izdvojimo u zasebnu mikroslu\u017ebu i pokrenemo u zasebnom procesu, kontejneru. To \u0107e biti zasebna usluga s vezom prema bazi podataka monolita i onim tablicama koje se ne odnose izravno na njega. Monolit \u0107e jo\u0161 uvijek komunicirati za \u010ditanje s odvojenom dijelom. <\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" src=\"\/wp-content\/uploads\/2019\/07\/36011f4e6be4f6a2f19f2f074b645dcb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKasnije \u0107emo ukloniti tu vezu, tj. \u010ditanje podataka monolitne aplikacije iz odvojenih tablica tako\u0111er \u0107emo prevesti na API.<\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" src=\"\/wp-content\/uploads\/2019\/07\/290f91bbfccac2a4b384078e4cf4e337.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNakon toga izdvojit \u0107emo iz zajedni\u010dke BDP tablice s kojima radi samo nova mikroslu\u017eba. Mo\u017eemo premjestiti tablice u zasebnu shemu ili \u010dak u zasebnu fizi\u010dku BDP. Ostala je veza za \u010ditanje izme\u0111u mikroslu\u017ebe i BDP-a monolita, ali u tome nema ni\u010dega stra\u0161nog, u takvoj konfiguraciji on mo\u017ee opstati dovoljno dugo.<\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" src=\"\/wp-content\/uploads\/2019\/07\/ab947ac6a38ffbccd4e2b51103aef609.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPosljednji korak je potpuno ukloniti sve veze. U tom slu\u010daju, mo\u017eda \u0107e nam trebati migracija podataka iz glavne baze. Ponekad \u017eelimo ponovo iskoristiti neke replicirane podatke ili referentne podatke iz vanjskih sustava u vi\u0161e baza. To se neprekidno doga\u0111a.<\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" 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>Odjel za preradu.<\/b> Ova metoda je vrlo sli\u010dna prvoj, samo ide obrnutim redoslijedom. Odmah odvajamo novu bazu podataka i novu mikroservisnu jedinicu koja komunicira s monolitom putem API-ja. No, ostaje set tablica baze podataka koje \u017eelimo u budu\u0107nosti ukloniti. Vi\u0161e nam nisu potrebne, u novom modelu su zamijenjene.<\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" src=\"\/wp-content\/uploads\/2019\/07\/c94932033e47cfa1fd56595ab9a19246.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKako bi ova shema radila, vjerojatno \u0107e nam trebati prijelazno razdoblje.<\/p>\n<p>Dalje postoje dva mogu\u0107a pristupa.<\/p>\n<p><b>Prvi<\/b>: dupliciramo sve podatke u novim i starim bazama. U tom slu\u010daju dolazi do redundancije podataka, mogu se javiti problemi s sinkronizacijom. Me\u0111utim, mo\u017eemo imati dva razli\u010dita klijenta. Jedan \u0107e raditi s novom verzijom, drugi sa starom.<\/p>\n<p><b>Drugi<\/b>: dijelimo podatke prema nekom poslovnom kriteriju. Na primjer, imali smo 5 proizvoda koji su pohranjeni u staroj bazi podataka. \u0160esti u okviru nove poslovne zada\u0107e stavljamo u novu bazu podataka. No, trebat \u0107e nam API Gateway koji \u0107e sinkronizirati te podatke i pokazati klijentu odakle i \u0161to treba uzeti.<\/p>\n<p>Oba pristupa su funkcionalna, odaberite ovisno o situaciji.<\/p>\n<p>Nakon \u0161to se uvjerimo da sve radi, dio monolita koji radi sa starim strukturama baze podataka mo\u017ee se isklju\u010diti. <\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" src=\"\/wp-content\/uploads\/2019\/07\/973bf5015bdf49a290a5b901f89628cc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nZadnji korak \u0107e biti brisanje starih struktura podataka. <\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" src=\"\/wp-content\/uploads\/2019\/07\/fe83acc07077b7eb3717138e3c20c005.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nZaklju\u010dak je da imamo problema s bazama podataka: te\u0161ko ih je koristiti u usporedbi s izvorom koda, te\u017ee ih je dijeliti, ali to se mo\u017ee i treba raditi. Prona\u0161li smo neke na\u010dine koji omogu\u0107uju relativno sigurnu provedbu, jer je lako napraviti gre\u0161ku s podacima nego s izvorom koda. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"12\"><\/a><\/noindex><b><\/p>\n<h3>Rad s izvorni kodom<\/h3>\n<p><\/b><br \/>\nOvako je izgledala shema izvornog koda kada smo po\u010deli analizirati monolitni projekt.<\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" src=\"\/wp-content\/uploads\/2019\/07\/a6d886e37117ccf8f63106d6616aa653.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMo\u017ee se uvjetno podijeliti na tri sloja. To je sloj pokrenutih modula, plug-inova, servisa i pojedina\u010dnih aktivnosti. U su\u0161tini, to su bile ulazne to\u010dke unutar monolitnog rje\u0161enja. Sve su bile \u010dvrsto povezane slojem Common. U njemu se nalazila poslovna logika koju su servisi zajedni\u010dki koristili, te mno\u0161tvo veze. Svaki servis i plug-in koristio je do 10 i vi\u0161e common biblioteka, ovisno o njihovoj veli\u010dini i savjesti programera.<\/p>\n<p>Imali smo sre\u0107e, imali smo infrastrukturne biblioteke koje su se mogle koristiti zasebno. <\/p>\n<p>Ponekad se doga\u0111alo da neki Common objekti zapravo nisu pripadali ovom sloju, ve\u0107 su bili infrastrukturne biblioteke. To se rje\u0161avalo preimenovanjem.<\/p>\n<p>Najvi\u0161e brige izazivali su ograni\u010deni konteksti. Ponekad su se 3-4 konteksta mije\u0161ala u jednoj Common biblioteci i koristila jedni druge unutar istih poslovnih funkcija. Trebalo je shvatiti gdje se to mo\u017ee podijeliti i prema kojim granicama, te \u0161to dalje raditi s mapiranjem tog razdvajanja na biblioteke izvornog koda.<\/p>\n<p>Formulirali smo nekoliko pravila za proces razdvajanja koda.<\/p>\n<p><b>Prvo<\/b>: vi\u0161e nismo htjeli zajedni\u010dko kori\u0161tenje poslovne logike izme\u0111u servisa, aktivnosti i plug-inova. \u017deljeli smo u\u010diniti poslovnu logiku neovisnom unutar mikroservisa. S druge strane, mikroservisi bi, idealno, trebali biti smatrani servisima koji postoje potpuno neovisno. Smatram da je ovaj pristup pomalo rasipan, a i te\u0161ko ga je posti\u0107i, jer, na primjer, servisi napisani u C# \u0107e se ionako povezivati standardnom bibliotekom. Na\u0161 sustav je napisan u C#, druge tehnologije zasad nismo koristili. Stoga smo odlu\u010dili da si mo\u017eemo priu\u0161titi kori\u0161tenje zajedni\u010dkih tehni\u010dkih biblioteka. Najva\u017enije je da u njima ne bude nikakvih fragmenata poslovne logike. Ako imate zgodnu omotnicu oko ORM-a koju koristite, tada je preseljenje iz servisa u servis vrlo skupo.<\/p>\n<p>Na\u0161 tim je obo\u017eavatelj predmetno orijentiranog projektiranja, stoga nam je \"lukova arhitektura\" savr\u0161eno odgovarala. Temelj na\u0161ih usluga nije bio sloj za pristup podacima, ve\u0107 skup s domenom logike koja sadr\u017ei samo poslovnu logiku i li\u0161ena je veza s infrastrukturom. Na ovaj na\u010din mo\u017eemo neovisno razvijati domensku skupinu za rje\u0161avanje problema povezanih s okvirima.<\/p>\n<p>U ovoj fazi susreli smo se s prvim ozbiljnim problemom. Usluga je trebala referencirati jednu domensku skupinu, dok smo \u017eeljeli da logika bude neovisna, a tu nam je jako smetao princip DRY. Razvijatelji su \u017eeljeli izbje\u0107i dupliciranje ponovnim kori\u0161tenjem klasa iz susjednih skupina, \u0161to je rezultiralo ponovnim povezivanjem domena. Analizirali smo rezultate i odlu\u010dili da mo\u017eda problem le\u017ei i u strukturi skladi\u0161ta izvornog koda. Imali smo veliki repozitorij u kojem su le\u017eali svi izvorni kodovi. Rje\u0161enje za cijeli projekt vrlo je te\u0161ko bilo sastaviti na lokalnom ra\u010dunalu. Stoga su se za dijelove projekta stvarala mala odvojena rje\u0161enja i nitko nije zabranio dodavanje neke zajedni\u010dke ili domenske skupine i ponovno kori\u0161tenje. Jedini alat koji nam nije dopu\u0161tao to bilo je pregledavanje koda. No, ponekad je i on zaka\u0161njavao.<\/p>\n<p>Tada smo po\u010deli prelaziti na model s odvojenim repozitorijima. Poslovna logika prestala je prolaziti iz usluge u uslugu, a domene su stvarno postale neovisne. Ograni\u010deni konteksti se jasno podr\u017eavaju. Kako u tom procesu ponovno koristimo infrastrukturne biblioteke? Odvojili smo ih u poseban repozitorij, zatim ih stavili u Nuget pakete koje smo smjestili u Artifactory. Pri svakoj promjeni, izgradnja i objava odvijaju se automatski.<\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" src=\"\/wp-content\/uploads\/2019\/07\/8ddbc750dc7c6d397a459acf7825de90.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNa\u0161e usluge po\u010dele su se referirati na interne infrastrukturne pakete na isti na\u010din kao i na vanjske. Vanjske biblioteke preuzimamo iz Nugeta. Za rad s Artifactoryjem, gdje smo smjestili te pakete, koristili smo dva upravitelja paketa. U malim repozitorijima tako\u0111er smo koristili Nuget. U repozitorijima s vi\u0161e usluga koristili smo Paket, koji osigurava ve\u0107u dosljednost verzija izme\u0111u modula.<\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" src=\"\/wp-content\/uploads\/2019\/07\/672a25a70a481bff68baebe963184ccd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDakle, radom na izvor kodu, malo promijeniv\u0161i arhitekturu i razdvajanjem repozitorija, \u010dinimo na\u0161e usluge neovisnijima.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"13\"><\/a><\/noindex><b><\/p>\n<h3>Problemi infrastrukture<\/h3>\n<p><\/b><br \/>\nVe\u0107ina nedostatka pri prelasku na mikroslu\u017ebe povezana je s infrastrukturom. Trebat \u0107e vam automatizirano implementiranje, potrebne su nove biblioteke za rad s infrastrukturom.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"16\"><\/a><\/noindex><b>Ru\u010dno postavljanje u okru\u017eenja<\/b><\/p>\n<p>Prvotno smo rje\u0161enja za okru\u017eenje instalirali ru\u010dno. Kako bismo automatizirali taj proces, stvorili smo CI\/CD kanal. Odabrali smo proces neprekidne isporuke, jer je neprekidno implementiranje za nas trenutno neprihvatljivo s aspekta poslovnih procesa. Stoga se pu\u0161tanje u rad vr\u0161i pritiskom na gumb, dok se testiranje odvija automatski.<\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" src=\"\/wp-content\/uploads\/2019\/07\/0fc092326a48813398c6f3a031197bab.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMi koristimo Atlassian, Bitbucket za pohranu izvornih kodova i Bamboo za izradu. Svi\u0111a nam se pisanje skripti za izradu na Cakeu, jer je to isti C#. U Artifactory dolaze ve\u0107 gotovi paketi, a Ansible automatski ide na testne servere, nakon \u010dega ih odmah mo\u017eemo testirati.<\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" 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>Odvojeno logiranje<\/h3>\n<p><\/b><br \/>\nNekada, jedna od ideja monolita bila je osigurati zajedni\u010dko logiranje. Tako\u0111er smo trebali shvatiti \u0161to u\u010diniti s odvojenim logovima koji su smje\u0161teni na diskovima. Logovi se pi\u0161u u tekstualne datoteke. Odlu\u010dili smo koristiti standardni ELK stack. Nismo htjeli pisati direktno u ELK putem providera, ve\u0107 smo odlu\u010dili doraditi tekstualne logove i zapisivati u njih ID traganja u obliku identifikatora, dodaju\u0107i naziv usluge, kako bismo te logove mogli kasnije analizirati.<\/p>\n<p><img decoding=\"async\" alt=\"Prijelaz s monolita na mikroservise: povijest i praksa\" src=\"\/wp-content\/uploads\/2019\/07\/8e58c66ac134e65abe34b59939f31483.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPomo\u0107u Filebeata dobivamo mogu\u0107nost prikupljanja na\u0161ih logova s <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/hr\/server\/\"   title=\"poslu\u017eitelja\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"1338\">poslu\u017eitelja<\/a>, a zatim ih pretvarati, uz pomo\u0107 Kiban\u0435 graditi upite u UI i gledati kako je poziv prolazio izme\u0111u usluga. U tome zna\u010dajno poma\u017ee ID traganja.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"15\"><\/a><\/noindex><b><\/p>\n<h3>Testiranje i debagiranje povezanih servisa<\/h3>\n<p><\/b><br \/>\nIsprva nismo u potpunosti razumjeli kako da debagujemo razvijene servise. S monolitom je sve bilo jednostavno, pokretali smo ga na lokalnom ra\u010dunalu. Tako\u0111er smo poku\u0161avali raditi s mikroservisima, ali ponekad za potpuno pokretanje jednog mikroservisa treba pokrenuti i nekoliko drugih, \u0161to je neudobno. Shvatili smo da je potrebno pre\u0107i na model u kojem na lokalnom ra\u010dunalu ostavljamo samo servis ili servise koje \u017eelimo debagovati. Ostali servisi koriste se s poslu\u017eitelja koji se konfiguracijom podudaraju s produkcijom. Nakon debagovanja, prilikom testiranja, na testni poslu\u017eitelj daju se samo izmijenjeni servisi za svaku zada\u0107u. Tako se testira rje\u0161enje u obliku u kojem \u0107e se ono u budu\u0107nosti na\u0107i u produkciji.<\/p>\n<p>Postoje poslu\u017eitelji na kojima su samo produkcijske verzije servisa. Ti poslu\u017eitelji su potrebni u slu\u010daju incidenata, za provjeru isporuke prije implementacije i za unutarnje obuke.<\/p>\n<p>Dodali smo proces automatskog testiranja pomo\u0107u popularne biblioteke Specflow. Testovi se automatski pokre\u0107u pomo\u0107u NUnit-a odmah nakon implementacije iz Ansibla. Ako je pokrivenost zadatka potpuno automatska, onda nema potrebe za ru\u010dnim testiranjem. Iako ponekad dodatno ru\u010dno testiranje jo\u0161 uvijek mo\u017ee biti potrebno. Za odre\u0111ivanje koji testovi pokrenuti za odre\u0111enu zada\u0107u koristimo oznake u Jiri.<\/p>\n<p>Dodatno je porasla potreba za testiranjem optere\u0107enja, koje se ranije provodilo samo u rijetkim slu\u010dajevima. Za pokretanje testova koristimo JMeter, za njihovo pohranjivanje \u2014 InfluxDB, a za izradu grafova procesa \u2014 Grafanu.<\/p>\n<p><b><\/p>\n<h3>\u0160to smo postigli?<\/h3>\n<p><\/b><br \/>\nPrvo, oslobodili smo se pojma \"izdanje\". Nestali su dvomjese\u010dni monstruozni izdava\u010dki procesi, kada se ovaj mega sustav implementirao u produkcijsko okru\u017eenje, privremeno kr\u0161e\u0107i poslovne procese. Sada implementiramo servise u prosjeku svaka 1,5 dana, grupiraju\u0107i ih, jer ulaze u upotrebu nakon odobrenja.<\/p>\n<p>U na\u0161em sustavu nema fatalnih kvarova. Ako smo objavili mikroservis s gre\u0161kom, onda \u0107e povezana funkcionalnost biti slomljena, dok ostala funkcionalnost ne\u0107e biti pogo\u0111ena. To zna\u010dajno pobolj\u0161ava korisni\u010dko iskustvo.<\/p>\n<p>Mo\u017eemo upravljati rasporedom implementacije. Mogu\u0107e je izdvojiti grupe servisa od ostatka re\u0161enja ako to bude potrebno.<\/p>\n<p>Osim toga, zna\u010dajno smo smanjili problem sa velikim redom za dorade. Imamo posebne proizvodne timove koji rade na delu servisa nezavisno. Tu ve\u0107 dobro odgovara Scrum proces. Konkretnom timu mo\u017ee biti dodeljen poseban vlasnik proizvoda koji mu postavlja zadatke. <\/p>\n<p><b><\/p>\n<h3>Sa\u017eetak<\/h3>\n<p><\/b><\/p>\n<ul>\n<li>Mikroservisi su pogodna re\u0161enja za dekompoziciju slo\u017eenih sistema. Tokom procesa po\u010dinjemo da razumemo \u0161ta imamo u na\u0161em sistemu, koja su ograni\u010dena konteksta i gde su njihove granice. To omogu\u0107ava pravilno raspore\u0111ivanje dorada po modulima i spre\u010dava zamr\u0161avanje koda. <\/li>\n<li>Mikroservisi donose organizacijske prednosti. O njima se \u010desto govori samo kao o arhitekturi, ali svaka arhitektura je potrebna za re\u0161avanje poslovnih potreba, a ne sama po sebi. Stoga mo\u017eemo re\u0107i da su mikroservisi pogodna re\u0161enja za re\u0161avanje zadataka malim timovima, s obzirom na to da je Scrum trenutno vrlo popularan.<\/li>\n<li>Razdvajanju \u2014 to je iterativni proces. Ne mo\u017eete uzeti aplikaciju i jednostavno je podeliti na mikroservise. Proizvod koji dobijete te\u0161ko da \u0107e biti funkcionalan. Pri izdavanju mikroservisa, isplativo je prepisivati postoje\u0107i legacy, tj. pretvarati ga u kod koji nam se svi\u0111a i bolje zadovoljava potrebe poslovanja u pogledu funkcionalnosti i brzine.\n<p><i>Malo upozorenje:<\/i> tro\u0161kovi prelaska na mikroservise su prili\u010dno zna\u010dajni. Samo re\u0161avanje problema infrastrukture oduzelo je mnogo vremena. Stoga, ako imate malu aplikaciju koja ne zahteva specifi\u010dno skaliranje, ako nema mnogo korisnika koji se bore za pa\u017enju i vreme va\u0161eg tima, onda mo\u017eda mikroservisi nisu ono \u0161to vam danas treba. To je prili\u010dno skupo. Ako zapo\u010dnete proces sa mikroservisima, tro\u0161kovi \u0107e u po\u010detku biti ve\u0107i nego da isti projekat zapo\u010dnete razvojem monolita. <\/p>\n<p>P.S. Emotivnija pri\u010da (kao da je li\u010dno vama) \u2013 po <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=qTNbx18DzpQ\">vezi<\/a><\/noindex>. <br \/>\nOvde je puna verzija izve\u0161taja.<\/li>\n<\/ul>\n<p>Izvor: <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.4 - 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\/hr\/blog\/administrirovanie\/perehod-ot-monolita-k-mikroservisam-istoriya-i-praktika\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"hr_HR\" \/>\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\/hr\/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\udd47Prijelaz s monolita na mikroservise: pri\u010da i praksa | ProHoster","description":"U ovom \u010dlanku \u0107u govoriti o tome kako se projekt na kojem radim transformirao iz velikog monolita u skup mikroservisa. Projekt je zapo\u010deo svoju pri\u010du davno, po\u010detkom 2000-ih.","canonical_url":"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/perehod-ot-monolita-k-mikroservisam-istoriya-i-praktika","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"hr_HR","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\/hr\/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\/hr\/wp-json\/wp\/v2\/posts\/35906","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/comments?post=35906"}],"version-history":[{"count":1,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts\/35906\/revisions"}],"predecessor-version":[{"id":158582,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts\/35906\/revisions\/158582"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media\/26858"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media?parent=35906"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/categories?post=35906"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/tags?post=35906"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}