Novinky
Vývoj8 min čtení

Mikroslužby vs monolit: jakou architekturu zvolit pro firemní aplikaci

Mikroslužby se předepisují mnohem častěji, než se vyplácejí. Podívejme se střízlivě na to, co monolit a mikroslužby v praxi znamenají, jaká je skutečná provozní cena rozdělení systému a proč je modulární monolit pro většinu firem správná odpověď.

Otázka „mikroslužby, nebo monolit?" padne skoro na každém kick-offu většího projektu. Obvykle ji položí někdo, kdo minulý týden četl článek o tom, jak velká technologická firma rozdělila svůj systém na dvě stě služeb a zrychlila vývoj. Problém je, že ta firma měla v době rozdělení několik set vývojářů, vlastní platformový tým a systém, který se už roky nedal nasadit bez noční odstávky. Vaše firma má pravděpodobně pět až patnáct lidí a systém, který teprve vzniká.

Architektura není soutěž v modernosti. Je to rozhodnutí o tom, kde budete platit složitost — jestli uvnitř jednoho procesu, nebo mezi desítkami procesů po síti. Obě možnosti mají svou cenu a ta druhá je mnohem vyšší, než se na prezentacích přiznává. Tento článek je pokusem o střízlivé srovnání, ne o obhajobu jedné strany.

Co monolit a mikroslužby ve skutečnosti znamenají

Monolit je aplikace, která se nasazuje jako jeden celek. Jeden repozitář, jeden build, jedna databáze, jeden proces (případně několik identických instancí za load balancerem). Uvnitř může být klidně rozdělená na moduly, vrstvy a domény — z pohledu nasazení je to však jedna jednotka.

Mikroslužby jsou opakem: systém rozdělený na samostatně nasaditelné služby, z nichž každá vlastní svá data a komunikuje s ostatními po síti — HTTP, gRPC nebo zprávy ve frontě. Klíčové slovo je samostatně nasaditelné. Pokud musíte pět služeb nasazovat najednou, protože si navzájem mění rozhraní, nemáte mikroslužby. Máte distribuovaný monolit — tedy nejhorší možnou kombinaci: složitost sítě bez výhody nezávislosti.

Toto rozlišení je důležitější, než se zdá. Většina systémů, které se označují za mikroslužbové, jsou ve skutečnosti distribuované monolity. Vznikly tak, že někdo rozdělil kód podle technických vrstev nebo podle databázových tabulek místo podle obchodních domén.

Pokud se dvě služby musí nasazovat společně, nejsou to dvě služby. Je to jedna služba s pomalým a nespolehlivým voláním funkce uprostřed.

Proč je monolit rozumné východisko

Pro většinu firemních systémů — interní systém, portál, e-shop na míru, aplikace pro správu agendy — je monolit správná volba a zůstává jí podstatně déle, než se běžně připouští.

Důvod je prozaický: na začátku projektu nevíte, kudy mají hranice domén vést. Zjistíte to až po pár měsících provozu, když uvidíte, které části se mění společně a které samostatně. V monolitu je posunutí hranice otázkou refaktoringu — přesunete třídy, upravíte volání, spustíte testy. Když je tatáž hranice zabetonovaná do síťového rozhraní mezi dvěma nasazenými službami, její posun znamená koordinovanou změnu, migraci dat a verzování API.

Monolit navíc dává věci, které v distribuovaném prostředí stojí hodně práce: transakce v jedné databázi, ladění s jedním stack trace, refaktoring napříč celou doménou jedním příkazem v IDE, lokální spuštění celého systému na notebooku. To nejsou maličkosti — to je většina každodenní práce vývojářského týmu. Jak se jednotlivé fáze takového projektu reálně vyvíjejí, jsme podrobněji rozepsali v článku o průběhu vývoje softwaru na míru.

Zkratka: Monolit volte jako výchozí možnost a odchylujte se od ní jen tehdy, když pro to máte konkrétní, pojmenovaný důvod — ne proto, že mikroslužby „jsou standard".

Skutečná provozní cena mikroslužeb

Mikroslužby nezaplatíte v kódu. Zaplatíte je v provozu a v lidech. Zde je přehled toho, co se reálně mění:

OblastMonolitMikroslužby
NasazeníJedna pipeline, jeden artefaktPipeline na službu, verzování rozhraní, kompatibilita mezi verzemi
Ladění chybyJeden stack traceDistribuované trasování napříč službami, korelační ID
Konzistence datDatabázová transakceSágy, kompenzační operace, eventual consistency
Lokální vývojdocker compose up a hotovoMock služby nebo sdílené vývojové prostředí
TestováníEnd-to-end testy nad jedním systémemKontraktové testy mezi službami plus integrační prostředí
Potřebné roleVývojářiVývojáři plus někdo, kdo vlastní platformu a infrastrukturu
Selhání částiAplikace běží, nebo neběžíČástečná selhání, timeouty, retry, circuit breakery

Nasazování a verzování

Nezávislé nasazování zní jako výhoda, dokud nezjistíte, že znamená i nezávislé verzování. Pokud služba A volá službu B, musíte řešit, co se stane, když běží nová A proti staré B. To vede ke zpětně kompatibilním změnám rozhraní, k obdobím, kdy existují dvě verze API najednou, a k disciplíně, kterou v malém týmu nikdo nemá čas držet. Principy, které tu pomáhají, jsme rozebrali u API-first architektury pro rostoucí firmy.

Pozorovatelnost

V monolitu víte, proč požadavek selhal, z logu a stack trace. V distribuovaném systému projde jedna uživatelská akce pěti službami a bez distribuovaného trasování a korelačních identifikátorů je hledání příčiny hádání. Pozorovatelnost v mikroslužbách není příjemný doplněk — je to podmínka provozuschopnosti. A je třeba ji postavit a udržovat dřív, než ji začnete potřebovat.

Konzistence dat

Toto je nejpodceňovanější položka. Když každá služba vlastní svá data, přestanou existovat transakce napříč doménami. „Vytvoř objednávku, sniž stav skladu, rezervuj platbu" už není jedna atomická operace, ale sekvence kroků s kompenzacemi pro případ, že třetí krok selže. Kód, který byl v monolitu deset řádků, se změní na stavový automat s obsluhou chyb. Podobné výzvy při propojování systémů popisujeme i v textu o systémové integraci ERP, CRM a e-shopu.

Conwayův zákon: architektura kopíruje organizaci

Melvin Conway zformuloval jednoduché pozorování: systémy, které organizace navrhne, kopírují její komunikační struktury. V praxi to znamená, že architekturu nemůžete zvolit nezávisle na tom, jak jsou uspořádané týmy.

Mikroslužby fungují tehdy, když každou službu vlastní tým, který ji vyvíjí i provozuje, a když týmy mezi sebou komunikují přes rozhraní místo přes porady. U pěti lidí takové rozdělení neexistuje — všichni dělají na všem. Rozdělení systému na osm služeb v pětičlenném týmu nepřinese nezávislost. Přinese osm pipeline, osm sad konfigurace a jednoho člověka, který při každém vydání kontroluje, jestli sedí verze.

Praktické pravidlo: počet služeb by neměl výrazně převyšovat počet týmů, které je dokážou vlastnit. Pokud máte jeden tým, mějte jednu službu — případně dvě, pokud je pro druhou skutečný důvod.

Modulární monolit jako pragmatický střed

Modulární monolit je odpovědí na většinu situací, ve kterých firma zvažuje mikroslužby. Jde o jednu nasazovací jednotku, která je uvnitř rozdělená na moduly podle obchodních domén — objednávky, sklad, fakturace, uživatelé — s explicitními hranicemi.

V praxi to znamená:

  • Modul vlastní své tabulky. Jiné moduly do nich nesahají přímo, ale přes veřejné rozhraní modulu.
  • Závislosti jdou jedním směrem. Zakážete cyklické závislosti mezi moduly a vynucujete to nástrojem, ne dohodou na poradě.
  • Komunikace mezi moduly je explicitní. Volání rozhraní nebo doménová událost — ne přímé volání interní třídy.
  • Testy se dají psát na úrovni modulu. Modul má vlastní testovací sadu, která nepotřebuje zbytek systému.

Výsledkem je systém, který má hranice mikroslužeb, ale zatím nemá síť mezi nimi. Když později zjistíte, že modul „fakturace" opravdu potřebuje samostatný cyklus nasazení, jeho vyčlenění je práce na týdny, ne přepis systému. A pokud to nikdy nezjistíte, ušetřili jste roky provozní režie.

Modulární monolit se dá také slušně škálovat — horizontálně, replikami za load balancerem. Většinu problémů s výkonem firemních aplikací nezpůsobuje architektura, ale databázové dotazy a chybějící indexy; k tomu jsme napsali samostatný text o škálování webové aplikace s růstem firmy.

Konkrétní signály, které ospravedlňují vyčlenění služby

Vyčleňujte jednotlivě a z důvodu, který umíte pojmenovat. Reálné signály:

  • Odlišný profil zátěže. Generování PDF nebo zpracování obrázků si žádá jiné zdroje a jiné škálování než zbytek aplikace.
  • Odlišný cyklus nasazení. Komponenta, která se mění denně, brzdí systém vydávaný jednou za měsíc — a naopak.
  • Jiný vlastník. Část systému přebírá samostatný tým s vlastní odpovědností za provoz.
  • Regulační nebo bezpečnostní izolace. Zpracování citlivých údajů, které má být oddělené i infrastrukturně.
  • Odlišná technologie. Část problému se reálně lépe řeší v jiném jazyce nebo runtime.

Co signál není: „chceme být škálovatelní", „mikroslužby jsou moderní", „chceme na to použít jinou technologii, protože nás zajímá".

Rizika migrace a jak je snížit

Nejdražší chyba není zvolit monolit. Je jí rozhodnutí přepsat fungující monolit na mikroslužby najednou — tedy zastavit vývoj funkcí na rok, postavit nový systém a pak přepnout. Takové projekty se zpravidla protáhnou, mezitím se mění původní systém a nový nikdy nedožene realitu.

Bezpečnější postup je inkrementální: nejprve vyčistit hranice modulů uvnitř monolitu, pak vybrat jeden modul s nejsilnějším důvodem a vyvést ho ven, provozovat oba systémy souběžně a až po ověření přesunout data. Podobnou logiku postupných kroků popisujeme i u migrace legacy systému na moderní platformu.

Pozor: Pokud nemáte automatizované testy, monitoring a spolehlivou CI/CD pipeline, mikroslužby situaci nezlepší — jen znásobí počet míst, kde vám tyto věci budou chybět.

Shrnutí

Mikroslužby řeší organizační problém velkých firem: příliš mnoho lidí na jednu nasazovací jednotku. Pokud tento problém nemáte, řešíte jimi něco, co vás netrápí, a platíte za to provozní složitostí, kterou budete cítit každý den.

Pro středně velký firemní systém a tým do zhruba deseti lidí je správnou odpovědí téměř vždy modulární monolit s poctivě dodrženými hranicemi domén. Z něj se dá vyjít směrem ke službám tehdy, když pro to přijde konkrétní důvod — a tehdy to bude řízené vyčlenění, ne skok do neznáma. Při návrhu architektury firemních systémů ve vývoji na míru proto standardně začínáme otázkou, kudy vedou hranice domén, ne otázkou, kolik bude služeb.

Pokud zvažujete, jestli váš systém už dozrál na rozdělení, nebo naopak plánujete nový a chcete se vyhnout předčasné fragmentaci, ozvěte se nám a projdeme si vaši situaci konkrétně.

INTERFASE