Abstrakt Volba mezi monolitickou a mikroservisní architekturou patří mezi nejzásadnější rozhodnutí v moderním softwarovém inženýrství. Článek shrnuje silné a slabé stránky obou přístupů, představuje modulární monolit jako pragmatickou střední cestu a nabízí rozhodovací rámec opřený o velikost týmu, provozní zralost a obchodní požadavky. Vychází ze známých případových studií i z dat o nákladech, latenci a provozní složitosti.
1. Od hype k realitě
Mikroservisní architektura se po úspěších Netflixu a Amazonu stala dominantním trendem. Gartner však ukazuje, že obor opustil fázi přehnaných očekávání a vstoupil do období realismu. Veřejně dokumentované návraty k monolitu to potvrzují: Amazon Prime Video v roce 2023 snížil náklady o 90 procent přechodem z mikroslužeb zpět na monolitickou architekturu. Segment v roce 2018 konsolidoval více než sto čtyřicet mikroslužeb do jediné aplikace. Tým Istio v roce 2020 sloučil své kontrolní mikroslužby kvůli výkonu.
Studie ThoughtWorks z roku 2024 uvádí, že 66 procent projektů začínajících s mikroslužbami bez jasné potřeby selhává nebo výrazně překračuje rozpočet. Průměrné navýšení provozních nákladů činí 147 procent při předčasném přechodu a doba do produkce je trojnásobně delší než u dobře strukturovaného monolitu.
2. Monolitická architektura: síla jednoduchosti
Monolit dnes neznamená automaticky špagetový kód. Modulární monolit kombinuje jeden nasazovací artefakt s jasně oddělenými moduly, definovanými API a vynucenými hranicemi mezi balíčky. Vývojářům přináší rychlejší iterace, jednodušší ladění a předvídatelný provoz.
Mezi klíčové výhody patří jediná deployment pipeline, jeden artefakt pro rollback a jednotná observabilita. Stack trace obsahuje celý kontext požadavku, lokální vývoj funguje bez potřeby orchestrace, transakce jsou ACID na úrovni jedné databáze.
Výkonnostní rozdíly jsou rovněž významné. Operace, která v monolitu znamená tři spojené dotazy s latencí kolem pěti milisekund, vyžaduje v mikroslužbách tři síťová volání s orchestrační režií, což typicky představuje padesát milisekund a více. Při řetězení několika takových volání latence rychle narůstá.
Modulární monolit lze v Javě a Spring Boot strukturovat tak, že každý modul vystavuje pouze veřejné API přes DTO objekty, interní třídy zůstávají skryté a hranice se vynucují architektonickými testy například pomocí ArchUnit. Pro horizontální škálování stačí stejnou aplikaci nasadit do více replik za load balancer.
3. Mikroslužby: distribuovaná složitost
Mikroservisní architektura otevírá technologickou diverzitu, nezávislé nasazení jednotlivých služeb a cílené škálování úzkých míst. Současně přináší daň, kterou mnoho organizací podceňuje.
Síťová režie je první z nákladů. Každé volání mezi službami zahrnuje serializaci, autentizaci, distribuované trasování a obvykle také circuit breaker. Distribuované transakce vyžadují vzory typu SAGA, které řeší kompenzace v opačném pořadí v případě chyby. Eventual consistency je realita, se kterou se musí vývojáři i produktoví manažeři smířit.
Provozní složitost roste lineárně až exponenciálně. Pro dvacet mikroslužeb je třeba spravovat zhruba dvacet pipeline, dvacet nasazení do Kubernetes, desítky databází a cache, sto a více pravidel pro alerty a desítky monitorovacích dashboardů. Monolit s ekvivalentní funkcionalitou vyžaduje řádově méně provozních artefaktů.
Pro úspěšný provoz je nezbytný service mesh typu Istio nebo Linkerd, distribuované trasování přes OpenTelemetry, centralizované logování a vyzrálá platformová tým. Bez těchto investic se z mikroslužeb stane distribuovaný monolit s nejhoršími vlastnostmi obou přístupů.
4. Rozhodovací rámec
Volba architektury by se neměla opírat o módu, ale o kvantitativní kritéria. Klíčovými proměnnými jsou velikost týmu, požadavky na škálování, frekvence nasazení, doménová složitost, požadavky na konzistenci dat a provozní zralost.
Týmy do deseti vývojářů by měly téměř vždy zvolit monolit nebo modulární monolit. Týmy do třiceti lidí mohou pracovat efektivně s modulárním monolitem a postupně extrahovat ty služby, kde to dává smysl. Mikroservisní architektura se vyplatí typicky až nad padesát vývojářů s jasně oddělenými bounded contexts a vyzrálou platformou.
Z hlediska výkonu platí jednoduché pravidlo. Pokud aplikace zvládá pod tisíc požadavků za sekundu, monolit je dostatečný. Mezi tisícem a deseti tisíci může být modulární monolit s vertikálním a horizontálním škálováním optimální. Nad deset tisíc požadavků za sekundu se vyplatí extrahovat konkrétní úzká hrdla do samostatných služeb.
5. Případové studie
Shopify představuje úspěšný příklad modulárního monolitu. Z původní Rails aplikace s tisícem požadavků za minutu vyrostl systém zvládající o Black Friday 2023 přes 3,5 milionu požadavků za minutu při dostupnosti 99,99 procenta. Filozofie zní: monolit jako výchozí volba, služby jako výjimka.
Segment naopak ukazuje, co se stane při předčasném rozdělení. Po konsolidaci 140 mikroslužeb do jednoho Go binárního souboru klesla latence p99 z 3000 milisekund na 200 milisekund, chybovost z 2,5 procenta na 0,1 procenta a infrastrukturní náklady o 80 procent.
Uber kombinuje oba přístupy přes Domain-Oriented Microservice Architecture. Každá doména je interně monolitická, mezi doménami komunikuje přes definovaná API a sdílené platformové služby. Tento hybridní přístup vyvažuje provozní složitost a vývojovou agilitu.
6. Migrace a anti-patterny
Při přechodu z monolitu na mikroslužby se osvědčil vzor Strangler Fig. Nové funkcionality se postupně přesměrovávají do nových služeb pomocí feature flagů, paralelní validace ověřuje konzistenci výsledků a v případě chyby je možný okamžitý fallback.
Konsolidace opačným směrem začíná identifikací kandidátů: služby s nízkým provozem, vysokou vazbou na ostatní a malým dedikovaným týmem jsou prioritní. Datová migrace probíhá přes Change Data Capture, čtení se přepíná před zápisem a původní databáze se vyřazuje až po ověření.
Nejhorším výsledkem je distribuovaný monolit. Charakterizují ho synchronní volání mezi všemi službami, sdílená databáze, koordinované nasazení a vzájemné rozbíjení změn. Stejně problematické jsou chatty services, kde získání jednoho objednávkového záznamu spustí desítky síťových volání. Řešením jsou batch API, asynchronní zpracování přes události a v některých případech GraphQL Federation.
7. Závěr
Volba mezi monolitem a mikroslužbami není binární. Modulární monolit a hybridní architektury jsou pro většinu organizací pragmatickou volbou. Architektonické rozhodnutí by mělo vycházet z měřitelných kritérií: velikosti a struktury týmu, provozní zralosti, skutečných škálovacích potřeb a doménové složitosti.
Konkrétní doporučení pro nový projekt zní začít modulárním monolitem. V případě výkonnostních problémů nejprve zvážit cache a horizontální škálování, teprve poté extrahovat konkrétní úzká hrdla. Při problémech s koordinací týmů ověřit, zda jsou hranice domén skutečně jasné, jinak hrozí, že distribuce problém zhorší.
Architektura je prostředek, nikoliv cíl. Cílem je dodávat hodnotu zákazníkům spolehlivě a udržitelně. Volba architektury by této hodnotě měla sloužit, nikoliv ji určovat.
Zdroje:
- Fowler, M.: MonolithFirst, martinfowler.com
- Newman, S. (2024): Building Microservices, 2nd Edition
- Richardson, C. (2024): Microservices Patterns
- ThoughtWorks Technology Radar 2024
- DORA State of DevOps Report 2024
- AWS Well-Architected Framework