Mikroservisi: Rješenje i nova bolest
Netflix je riješio svoj problem, a pola industrije se zarazilo rješenjem koje nikad nije imalo dijagnozu.
Sredina 2010-ih. Negdje u Los Gatosu netko iz Netflixa upravo je pritisnuo „objavi” na blog postu, i taj klik će industriju koštati otprilike koliko i pokoji manji rat. Naslov je bio nešto poput „Kako smo razbili monolit i preživjeli” — pun grafova, pun kutijica sa strelicama, pun rečenica koje zvuče kao da ih je pisao netko koji je stvarno riješio stvaran problem. A monolit, da razjasnimo, nije ništa mistično: to je jedna velika aplikacija u kojoj je sav kod i cijela baza podataka na jednom mjestu, i sve se pokreće, mijenja i objavljuje zajedno, kao jedna cigla — dirneš jedan dio, moraš pažljivo s cijelom ciglom. Jer Netflix i jest riješio stvaran problem. Imali su desetke milijuna korisnika, sedam tisuća developera i infrastrukturni problem koji bi slomio svakog normalnog čovjeka. Mikroservisi su za njih bili spas. Legitiman, zaslužen, dokumentiran spas.
Problem je što je taj blog post pročitalo, otprilike, cijelo ostalo čovječanstvo koje piše kod.
Konferencije tih godina imaju osjećaj crkvenog sabora. Monolit je grijeh, star i sramotan, nešto za što se ispričavaš da ga još imaš — »radimo na tome da ga rastavimo, obećavam«. Mikroservisi su zrelost, su ozbiljnost, su znak da tvoja firma napokon misli kao odrasla. Svaki talk počinje istom rečenicom o skalabilnosti, a završava istim slajdom s logotipom Ubera, Amazona, Netflixa — firmi koje imaju probleme kakve devedeset i devet posto publike u dvorani nikad neće imati, ali koje sad svi u toj dvorani žele imati, jer imati taj problem znači da si stigao.
Ovo poglavlje govori o tome kako se jedna arhitektonska odluka, donesena iz stvarne nužde u jednoj zgradi u Los Gatosu, pretvorila u globalnu epidemiju rezanja sustava na komadiće — ne zato što je to trebalo, nego zato što je netko drugi to napravio i izgledalo je cool. Domino koji kreće od jednog bloga i jedne konferencijske pozornice pa se kotrlja kroz startupe, agencije, korporativne odjele IT-a, sve dok se ne zaustavi — a onda, godinama kasnije, krene natrag. Jer priča ima obrat, i on je otprilike ovakav: firma koja je najviše propovijedala mikroservise jednog dana, tiho, u jednom svom timu, vrati sve u monolit. I napiše o tome — pogađate — blog post.
Bilo je to koncem prvog desetljeća dvijetisućitih — post sa slikama kutijica povezanih strelicama i s tonom koji odiše samopouzdanjem ljudi koji su upravo riješili problem koji ti nemaš. Onda je netko iz te firme pozvan na konferenciju da to isto ispriča uživo, s pivom u ruci na afterpartyju, pred tri stotine developera koji grozničavo kucaju bilješke u aplikacije koje će zaboraviti ikad više otvoriti.
E tu je klik koji pokreće cijelu ovu lančanu reakciju — ne u kodu, ne u serveru, nego u glavi čovjeka koji sluša. Arhitektura se, ispada, ne širi papirima, nego pričama. Postoji čak i naziv za posao čiji je jedini zadatak pričati takve priče — developer advocate. Zvuči kao da čovjek brani developere na sudu, a zapravo mu je posao mjeriti se brojem ljudi koji su s njegovog izlaganja otišli uvjereni da moraju promijeniti nešto što im prije pola sata nije padalo na pamet (to se u marketinškom žargonu zove KPI — ključni pokazatelj uspješnosti, odnosno broj kojim šef mjeri je li netko dobro radio svoj posao). Nije to prljav posao ni zla namjera — čovjek stvarno vjeruje u ono što priča, i uglavnom ima i pravo, za SVOJU firmu. Problem nastaje kad tri stotine ljudi u publici zaključi da vrijedi i za njihovu.
Sad, prije nego počnem s prstom uperenim u konferencijske pozornice — dužan sam ti reći istinu, jer bez nje sve ovo poglavlje postaje jeftina karikatura: ideja mikroservisa je dobra. Stvarno dobra, za pravi problem. Mikroservis je, kad ga oljuštiš od buzzworda, mala, nezavisna usluga koja radi jednu stvar, ima svoju bazu (ili dio baze) i, najbitnije, svoj vlastiti deploy — a deploy je, jednostavno rečeno, trenutak kad nova verzija koda ide uživo, na prave servere, pred prave korisnike. Ne moraš, kad promijeniš jednu liniju u modulu za slanje e-mailova, ponovno pokrenuti i testirati cijelu aplikaciju od korisničkih računa do plaćanja do preporuka filmova. Pokreneš samo taj komadić. Netflix, koji u jednom trenutku ima stotine timova koji rade paralelno na istom proizvodu za stotinu milijuna korisnika širom planete, taj problem stvarno ima. Njima monolit nije nezgoda — njima je monolit kočnica koja bukvalno sprječava stotine ljudi da rade istovremeno bez da se međusobno gaze po nogama.
Dakle, popravak je bio ispravan. Za bolest koju su imali. Problem nije u lijeku. Problem je što je taj lijek, zapakiran u pitku priču s lijepim slajdovima, počeo padati niz grlo svakome tko je imao glavobolju, bez obzira ima li migrenu ili je samo loše spao s kreveta. A upravo je ta sitnica — jedan blog post, jedan talk, jedno oduševljeno pljeskanje u dvorani — bila prvi domino koji je za par godina srušio budžete, timove i, u nekim slučajevima, cijele firme koje su pokušale biti Netflix, a imale su sedam developera i tisuću korisnika.

Prva posljedica: hype usvajanje
Prvi domino pada tiho, bez fanfara, u sobi za sastanke neke srednje firme koja ima, recimo, dvanaest developera i bazu korisnika koja bi stala na jednu dobro naplaćenu konferenciju. Netko je gledao onaj talk. Netko je pročitao onaj blog post. I sad, na sastanku, pada rečenica koja će tu firmu koštati sljedeće dvije godine: „moramo se maknuti od monolita, tako se danas radi”. Ne „imamo problem X koji monolit ne rješava” — nego tako se radi. Kao da je arhitektura moda, a monolit prošlogodišnja jakna koju se stidiš obući na izlazak.
I tu je vrijeme da kažemo naglas ono što svi znaju, a nitko ne piše u interne dokumente: velik dio ovog usvajanja nema veze s korisnicima, timovima, skalabilnošću ili bilo čim što firma stvarno treba. Ima veze s CV-om. Resume-driven development (razvoj vođen životopisom) nije uvreda, to je dijagnoza s imenom i prezimenom. Developer koji je dvije godine održavao Rails monolit gleda oglase za posao i vidi Kubernetes, gRPC, event-driven arhitekturu, service mesh — riječi koje monolit jednostavno nema razloga koristiti. Pa ih ubaci. Ne jer projekt treba, nego jer sljedeći projekt (kod drugog poslodavca, za veću plaću) traži da ih znaš. CV postaje arhitektonski dokument. Sustav se dizajnira da impresionira buduće ispitivače na razgovoru za posao, ne da rješava problem koji trenutno postoji na stolu. Zvuči kao zloba. Nije. Zvuči kao karikatura. Nije ni to — pitaj bilo kojeg tech leada (iskusnijeg developera koji vodi tim i donosi te odluke) koji je ikad odbijao prijedlog „razbijmo to na servise” i pitao zauzvrat samo jedno: koji je problem koji ovo rješava. Tišina je odgovor koji čuje prečesto.
A gdje ima potražnje, tamo nikad dugo ne nedostaje ponude. Konzultanti se množe brzinom kojom se širi svaka nova crkva — jer to i jest nova crkva, samo s drugim vokabularom. Isti model kao i uvijek, samo prekrojen: dođi, propovijedaj strah od zastarjelosti, naplati transformaciju, otiđi prije nego što stigneš arhitekturu vidjeti u produkciji (na pravim serverima, s pravim korisnicima) šest mjeseci kasnije. Prezentacije imaju identičnu strukturu iz firme u firmu — slajd s monolitom kao ružnim, isprepletenim blokom, slajd sa servisima kao čistim, lijepim šesterokutima povezanim tankim, urednim linijama. Nitko na tom slajdu ne crta linije koje predstavljaju retry logiku (kad sustav sam iznova pokuša poslati zahtjev koji je prvi put propao), timeoute (trenutak kad se odustane od čekanja odgovora jer je potrajalo previše) i tri tjedna debugiranja zašto je jedan poziv od pet propao bez traga. Ta se linija crta kasnije, kad konzultant već potpisuje ugovor s drugom firmom.
Domino je pao. Sitnica — jedan predavanje, jedan blog post — postala je pokret, pokret je postao industrija, a industrija je počela proizvoditi rješenja za probleme koje njezini klijenti nemaju. Sljedeći domino je onaj na koji svi ti šesterokuti sa slajdova nisu bili spremni: mreža.

Eskalacija: distribuirani monolit
E sad dolazi dio priče gdje se skida osmijeh. Firma je poslušala savjet, razrezala monolit na dvanaest lijepih, malih, samostalnih servisa, svaki sa svojim repozitorijem (mjestom, obično na GitHubu ili sličnom servisu, gdje se čuva kod baš tog servisa, odvojeno od svih ostalih), svojim deployem, svojim malim README-om koji nitko ne čita. Na papiru — čistoća. Svaki servis radi jednu stvar, radi je dobro, i teoretski ih možeš mijenjati nezavisno. Konferencijski slajd bi ovdje stavio kvačicu i prešao na sljedeću temu. Ali stvarnost ne prelazi na sljedeću temu, stvarnost ostaje s tobom u petak navečer kad servis za fakture ne može doći do servisa za korisnike i cijela aplikacija stoji kao ošamućena koka.
Evo u čemu je caka, i evo zašto je ova caka toliko podcijenjena da bi joj trebao spomenik od podcjenjenosti: razdvojio si servise, ali nisi razdvojio ovisnosti. Servis za fakture i dalje treba podatak iz servisa za korisnike. U monolitu je to bio jedan poziv funkcije, unutar istog procesa, unutar istog komada memorije, brz kao pomisao — mikrosekunde, bez drame. Sad je to poziv preko mreže. A mreža, prijatelju moj, ne radi u mikrosekundama. Mreža radi u stvarnom svijetu, gdje kablovi pucaju, paketi se gube, i DNS ima loš dan — a DNS je taj sustav koji ime servisa (recimo korisnici.firma.com) pretvara u stvarnu adresu na mreži, i kad on zapinje, ništa ne zna kome se obratiti. Tvoj lijepi, čisti poziv funkcije postane HTTP zahtjev koji čeka, čeka, i onda ili dobiješ odgovor ili dobiješ timeout, pa moraš odlučiti što s tim timeoutom — pokušati ponovno? Koliko puta? Koliko dugo čekati? Što ako i ponovni pokušaj padne? Cijela ta logika koju monolit nikad nije tražio od tebe, sad je tvoja domaća zadaća, za svaki od tih dvanaest servisa, za svaku vezu među njima.
Dakle složenost nije nestala. To je najbitnija rečenica ove sekcije, pa je ponavljam drugim riječima: složenost se nije smanjila rezanjem monolita, samo je preselila iz koda — gdje si je barem mogao vidjeti, debugirati, staviti breakpoint i gledati što se događa — u mrežu, gdje je nevidljiva, asinkrona i po definiciji zlobnija. U kodu je bug. U mreži je incident.
A da stvar bude još slikovitija, sve ovo je već bilo opisano, unaprijed, s kirurškom precizno šću, davne 1994. godine — dakle prije nego što je riječ „mikroservis” uopće postojala kao pojam. Peter Deutsch, inženjer u Sun Microsystemsu, sastavio je popis koji je ostao poznat kao zablude distribuiranog računarstva — izvorno sedam, kojima je nešto kasnije James Gosling dodao osmu. Osam pretpostavki koje svaki programer nesvjesno pravi kad prvi put poveže dva sustava preko mreže, i koje su, svaka do jedne, pogrešne.
Mreža je pouzdana — nije. Latencija je nula — nije. Propusnost je infinitna — nije. Mreža je sigurna — nije. Topologija se ne mijenja — mijenja se, i te kako. Postoji jedan administrator — nema, nikad nije bilo. Trošak transporta je nula — nije. Mreža je homogena — nije. Osam stavki, napisanih kad je internet bio nešto što je zujalo u podrumima sveučilišta, a čitaš ih danas i shvaćaš da je svaka od njih dijagnoza jednog konkretnog incidenta koji si imao ovaj mjesec. Deutsch nije predviđao mikroservise. Deutsch je samo znao da će netko, jednog dana, u nekom desetljeću, pomisliti da mreža nema cijenu. I zaboga, netko je pomislio. Cijela je dekada pomislila.
I evo najgore ironije cijele priče: čak su i ljudi koji su gurali mikroservise, koji su od njih napravili karijeru i knjigu, upozoravali na ovo. Martin Fowler, jedan od onih koji je najviše doprinio da se pojam mikroservisa uopće ozbiljno raspravlja, skovao je termin »microservices premium« — poštenu, gotovo dosadnu tvrdnju da mikroservisi dolaze s administrativnim porezom koji monolit nema, i da se taj porez isplati platiti tek kad korist od nezavisnog skaliranja i deploya prijeđe tu cijenu. Nije rekao „nikad ne koristite mikroservise”. Rekao je „prvo izračunajte je li vam se ovo isplati”, što je najmanje sexy savjet na svijetu i zato ga nitko na konferenciji ne citira naglas.
Tako je izgledala eskalacija: dvanaest servisa, dvanaest deploy pipelinea (niz automatiziranih koraka koji svaki put iznova pušta kod uživo, umnožen dvanaest puta jer svaki servis ima svoj), dvanaest sustava za logove — zapisnike što se točno dogodilo, po serviseru — koje treba ručno spojiti u jednu priču da bi shvatio zašto je zahtjev spor, i jedan tim od sedam ljudi koji sad umjesto pisanja koda uči čitati Jaeger dijagrame (crteže koji prikazuju kako jedan zahtjev putuje kroz svih dvanaest servisa) u dva ujutro. Distribuirani monolit — pojam koji je pogodio u sridu kao malo koji u ovoj industriji: sve mane monolita (sve je povezano, promjena na jednom mjestu razbija drugo), plus sve mane distribucije (mreža, latencija, retry logika), a nijedna od prednosti koje obje strane obećavaju.

Domino: povratak monolita (tiho)
I onda, negdje kad je desetljeće počelo trošiti posljednje mjesece, dogodila se čudna stvar. Isti ljudi koji su na konferencijama 2015. govorili »monolit je grob vaše karijere« počeli su govoriti nešto sasvim drugo. Zove se to »monolith first« — »najprije monolit«. Zvuči kao hereza, zvuči kao da je netko pojeo previše modularnog kolača i sad povraća zdrav razum, ali evo poante: čak je i Martin Fowler napisao da bi većina timova trebala početi s monolitom i mikroservise uvesti tek kad — i ako — im stvarno zatrebaju. Ne prije. Ne zato što je cool. Zato što ti zatrebaju.
Rodio se i novi-stari izraz: modularni monolit. Zvuči kao oksimoron, kao »veganski odrezak«, ali zapravo je samo priznanje da je cijelo vrijeme postojala treća opcija koju je hype pojeo. Podsjetimo: monolit je jedna velika aplikacija — sav kod, sva baza, sve na jednom mjestu, sve se pokreće i pušta uživo (deploya) zajedno. Modularni monolit uzme tu istu jednu bazu koda i jedan deploy, ali je iznutra podijeli na module s jasnim granicama, disciplinom kao da su odvojeni servisi — samo bez mreže između njih. Sva prednost organizacije, nijedna kazna latencije. Ono što bi svaki iole pametan senior mogao izgraditi 2014. da ga nitko nije uvjerio da je to sramota.
Firme koje su se vratile monolitu nisu bile rijetkost — cijela serija sličnih ispovijesti iz te faze ponavlja isti obrazac: firma rastavi monolit na mikroservise, izgubi godinu-dvije snage tima na infrastrukturu koja korisniku ne donosi baš ništa, izmjeri trošak, i vrati se natrag — pa o tome objavi tekst koji je, u biti, javno priznanje. Iskren podatak koji se vrti kroz te priče: timovi koji su se vratili monolitu prijavljuju znatan pad operativnog troška, samo zato što su prestali plaćati porez na postojanje mreže koja im od početka nije trebala.
A onda dođe udarac koji je, da ga je pisac fikcije smislio, urednik bi ga vratio s komentarom »previše ironično, nerealno«. 2023. godine tim koji radi na Amazon Prime Video objavi tehnički post: njihov servis za praćenje kvalitete videostreama, sastavljen od nekoliko mikroservisa i serverless komponenti — onih dijelova sustava gdje ne držiš svoj server, nego pokreneš kod »na zahtjev« kod pružatelja cloud usluga koji sam brine o infrastrukturi — koštao ih je previše i skalirao loše. Rješenje? Sve to spojili u jednu monolitnu aplikaciju. Ušteda: 90 posto infrastrukturnog troška. Amazon. Firma čiji su inženjeri prije deset godina na konferencijama objašnjavali svima ostalima kako se to radi. Vraća se kući i piše da je kod kuće, zapravo, bilo bolje.
Ispod svega toga, kad se dim razađe i konferencijski slajdovi sklone, stoji jedan zakon koji je stariji od riječi „mikroservis” za čitavih pedeset godina. Melvin Conway je 1968. napisao da će struktura sustava nužno oslikavati komunikacijsku strukturu organizacije koja ga gradi. Netflix nije imao stotine mikroservisa jer je to tehnički superiorno — imao ih je jer je imao stotine timova koji su morali raditi nezavisno, bez čekanja jedni na druge, bez sastanka za svaku promjenu jednog reda koda. Arhitektura je pratila organizacijski problem. Mikroservisi ne rješavaju tehnički problem skalabilnosti — najčešće ga stvaraju. Rješavaju ljudski problem: kako spriječiti da pet tisuća developera stane jedni drugima na crijeva.
Firma sa sedam developera nema taj problem. Nema ga, koliko god puta to napisao. Ona ima sedam ljudi koji sjede u istoj sobi (ili istom Slack kanalu) i mogu se dogovoriti za pet minuta o čemu god treba. Njoj Conwayev zakon poručuje: arhitektura treba pratiti organizaciju, a organizacija je — jedan tim. Pa neka joj arhitektura bude jedna, dok traje ono što je uvijek trajalo: dok stvarno ne zatreba drugo.

Svijet kakav poznaješ + pouka
I tu smo. Danas. Godina je svejedno koja — jer se ova scena vrti u petlji od 2018. naovamo. Sjedneš na sastanak o arhitekturi za novi projekt, netko otvori Miro board (ili whiteboard, ili zid, ovisno o generaciji trauma) i pita: monolit, mikroservisi ili serverless? I onda krene rasprava koja nije rasprava, nego recital citata s konferencija na kojima nitko od prisutnih nije bio. Jedan spominje Netflix. Drugi spominje da je čuo da se Amazon vratio na monolit. Treći spominje serverless kao da je to duhovno rješenje koje briše grijehe obaju prethodnih tabora. Nitko ne spominje koliko developera zapravo imaju. To je prvi znak da je razgovor uzalud.
Jer evo checklista koji nema logo, nema keynote, nema sponzora — i baš zato radi. Nije tehnički. Organizacijski je. Pravilo glasi: broj vaših timova bi trebao biti gornja granica broja vaših servisa, ne broj vaših mikroservisa na Pinterestu koji izgledaju cool na slajdu. Imaš tri tima? Onda ti treba tri, možda četiri servisa, ne osamnaest. Imaš jedan tim od sedam ljudi koji sve rade zajedno? Onda ti treba — i sad zvuči kao hereza, ali nije — jedan sustav. Modularan, uredan, s granicama unutar koda, ali jedan deploy, jedna baza, jedan tim koji ga sve razumije jer ga sve i piše.
I evo je, poanta cijele ove lančane reakcije, ona koja se provlačila kroz blog objave, kroz predavanja na konferencijama, kroz resume-driven arhitekturu, kroz distribuirani monolit koji ti se srušio u petak navečer, kroz Amazonov tim koji se vratio kući u monolit i uštedio devedeset posto: industrija ne uči iz principa. Industrija uči kopiranjem uspješnih. A uspješni su uspješni zbog konteksta koji se, po definiciji, ne da kopirati. Netflix nije uspio zato što je imao mikroservise. Netflix je imao mikroservise zato što je uspio — zato što je narastao do veličine gdje mu je ta arhitektura postala nužnost, ne ukras. Uzročnost je bila obrnuta cijelo vrijeme, i cijela industrija ju je pročitala unatrag.
Netflixov problem nije tvoj problem. Ta rečenica, da je ikad stala na naslovnicu neke konferencije umjesto na dno ovog poglavlja, uštedjela bi tehnološkoj industriji — bez ironije, bez pretjerivanja — milijarde dolara u nepotrebnim migracijama, propalim projektima prepisivanja cijelog sustava od nule i timovima koji su godinu dana radili infrastrukturu za praćenje zahtjeva kroz desetke servisa (zamisli GPS koji pratiš kroz cijelu dostavu paketa, samo za kod) — i sve to za sustav koji je opsluživao tristo korisnika. Ali rečenica ne prodaje karte za konferenciju. Ne prodaje konzultantske ugovore. Ne izgleda dobro na slajdu s Netflixovim logom u kutu. Zato je nitko nije stavio na naslovnicu. Stavili su je, ako uopće, u fusnotu — kao ovu.