Přejít k navigační liště

Zdroják » Webový vývoj » Skutečná cena mikroslužeb: výkon, složitost a režie

Skutečná cena mikroslužeb: výkon, složitost a režie

Články Webový vývoj

Mikroslužby slibují flexibilitu, nezávislé nasazování a snadné škálování týmů. Ve skutečnosti však každé síťové volání přidává latenci, zvyšuje režii a komplikuje dostupnost. Tento článek ukazuje, proč i jednoduché workflow může být v mikroslužbách pomalejší než v monolitu, doplněno o čísla, kód a praktické tipy pro rozhodování mezi architekturami.

Mikroslužby se v profesionálním vývoji prezentují jako „moderní“ architektura. Slíbí škálovatelnost, nezávislé nasazování a agilitu. Nicméně realita je taková, že síťové volání a distribuovaná komunikace mají výraznou režii, kterou je třeba zvažovat už při návrhu aplikace. Zjednodušené modely výkonu můžeme vyjádřit i jednoduchým „matematickým důkazem“, který porovnává monolitickou architekturu a mikroslužby.

Základní latence: proces vs. síť

První důležitý fakt je rozdíl mezi voláním funkce přímo v procesu a voláním služby přes síť:

Function call: 0.001ms (přímé volání v aplikaci)
HTTP request within same datacenter: 1–5ms (síťové volání)Code language: PHP (php)

To znamená, že síťové volání je 1 000× až 5 000× pomalejší než lokální volání. To samé platí pro volání mezi kontejnery nebo přes service mesh – i v datacentru je síť výrazně pomalejší než volání uvnitř procesu.

Reálný scénář: e‑shopový checkout

Abychom pochopili dopad tohoto rozdílu v latenci, podívejme se na typický pracovní tok během nákupu v e‑shopu:

Potřebné kroky:

  1. Validovat uživatelskou session
  2. Ověřit skladovou dostupnost
  3. Spočítat cenu dopravy
  4. Zpracovat platbu
  5. Vytvořit objednávku
  6. Odeslat potvrzovací e‑mail

V monolitu může takový proces vypadat zhruba takto:

6 volání funkcí × 0.001ms = 0.006ms
Database queries:          3 × 2ms   = 6ms
Externí API (platba):     150ms
----------------------------------
Celkem:                  ~156ms

V mikroslužbové architektuře jsou obdobné kroky něco jako:

await userService.validateSession()
await inventoryService.checkStock()
await shippingService.calculate()
await paymentService.process(paymentInfo)
await orderService.createOrder(orderData)
await notificationService.sendConfirmation()Code language: JavaScript (javascript)

Každý z těchto volání typicky zahrnuje:

  • síťovou latenci (~1-2 ms),
  • serializaci/deserializaci (~0.5 ms),
  • vlastní zpracování (~1-2 ms).

Pro šest služeb to dává přibližně:

6 služeb × ~3ms síťové režie = 18ms
DB dotazy:              6 × 2ms = 12ms
Externí API (platba):         150ms
-------------------------------------
Celkem:                     ~180ms

I v tomto jednoduchém příkladu je mikroslužbová verze přibližně o 15 % pomalejší než monolit.

„N+1 services“ – analogie N+1 dotazů

V databázových systémech známe problém N+1 dotazů, kdy místo jednoho optimalizovaného dotazu generujeme N dotazů kvůli špatnému přístupu. Podobně u mikroslužeb vzniká problém N+1 služeb, když logika vyžaduje řetězení služeb, které se nedají paralelizovat kvůli závislostem na datech:

-- efektivní monolitický dotaz
SELECT users.*, orders.*, recommendations.*
FROM users
LEFT JOIN orders ON orders.user_id = users.id
LEFT JOIN recommendations ON recommendations.user_id = users.id
WHERE users.id = $1
LIMIT 10;

Prototypická implementace v mikroslužbách:

// 1. Získat uživatele
const user = await userService.getUser(userId);        // ~3ms

// 2. Získat objednávky
const orders = await orderService.getOrders(userId);   // ~3ms

// 3. Získat doporučení
const orderIds = orders.map(o => o.id);
const recommendations =
  await recommendationService.getByOrders(orderIds);   // ~3msCode language: JavaScript (javascript)

Sekvenční provedení dává ~9 ms namísto ~5 ms v monolitu, tedy ~80 % pomalejší. A to opět za předpokladu absolutně perfektní sítě bez chyb nebo retry logiky.

Benchmark: jednoduchá CRUD aplikace

Autor benchmarku porovnával testovací aplikaci se čtyřmi entitami při zatížení 10 000 req/s:

MetrikaMonolitMikroslužbyZměna
p50 latency12 ms18 ms+50 %
p95 latency25 ms45 ms+80 %
p99 latency50 ms120 ms+140 %
Throughput10 0008 500-15 %
CPU usage45 %65 %+44 %
Memory usage512 MB2 GB+300 %
Network I/O50 MB/s180 MB/s+260 %

Tato čísla ukazují, že největší rozdíl je v tail latency (p99) a také v režii zdrojů – mikroslužby mohou vyžadovat výrazně více paměti, CPU i síťové propustnosti, i když teoreticky „škáluje“.

Rozklad jednoho volání služby

Abychom pochopili, co se děje pod pokličkou, rozebereme i anatomii jednoho síťového volání:

DNS resolution:             0.1ms (cached)
TCP handshake:             0.5ms
TLS handshake:             1.0ms
HTTP headers:             0.2ms
Request serialization:     0.3ms
Network transmission:      0.5ms
Service processing:        0.5ms
Response serialization:    0.3ms
Network transmission:      0.5ms
Response parsing:          0.2ms
--------------------------------------
Celkem:                  ~3.0msCode language: CSS (css)

Stejná operace jako lokální volání má ~0.001 ms. Latence síťového volání tak může být řádově tisíckrát až desetitisíckrát vyšší.

Kaskádové selhání a dostupnost

Další výrazný efekt mikroslužeb je řetězení availability. Pokud každá služba má 99,9 % dostupnost, celý řetězec pěti služeb má:

0.999^5 ≈ 0.995 = 99.5 %

To znamená přibližně 3,6 hodiny výpadků měsíčně namísto ~43 minut u jediné služby s 99,9 % dostupností. A toto je čistě teoretický scénář bez chyb v síti, bez deployů a bez retry logiky.

Skryté náklady: databáze a spojení

I když mikroslužby slibují oddělení dat, v praxi často sdílejí stejnou databázi. To přináší další režii:

  • každá služba má vlastní connection pool, který rychle vyčerpá limity DB serveru,
  • více paralelních spojení vede k vyšší lock contention,
  • cache se chová hůře díky různorodým přístupovým vzorcům.

Příklad z testů ukazuje, že monolit může používat 20-30 spojení s nízkou latencí, zatímco mikroslužby mohou vytvářet 60-80 spojení, což zvyšuje čekací doby zámků a celkovou latenci dotazů.

Přínos vs. náklady

Mikroslužby řeší organizaceční problémy, ne technické, což znamená, že:

  • umožňují nezávislé deploye týmů,
  • oddělují odpovědnosti,
  • podporují technologickou diverzitu.

Na druhé straně, pokud tyto organizační důvody neexistují, mikroslužby často přinášejí více problémů než řešení, což je potvrzeno i v různých diskusích okolo tohoto tématu.

Kdy mikroservisy dávají smysl

Prakticky je vhodné přejít na mikroslužby až když:

  • máte velké týmy s nezávislými doménami,
  • jednotlivé části systému vyžadují odlišné škálování,
  • existují jasné hranice a kontrakty mezi moduly,
  • organizační benefity převáží technické náklady.

Pokud tomu tak není, často je lepší zůstat u modulárního monolitu nebo hybridního modelu.

Závěr

Distribuované systémy mají svou vlastní logiku: mikroslužby nezmizí síťovou latenci, jen ji přesunou a znásobí, pokud jich je více a jejich volání nejsou efektivně navržena. Každé další volání služby přidává režii, zvyšuje latenci a komplikuje dostupnost.

Benchmarky, kódové příklady a simulace ukazují, že i relativně jednoduché workflow může být v mikroslužbách pomalejší a náročnější na zdroje než v monolitu, a to nezávisle na rychlosti samotného kódu nebo infrastruktury.

Mikroslužby přinášejí hlavně organizační benefity: umožňují nezávislé deploye, oddělují odpovědnosti a podporují technologickou diverzitu. Pokud tyto důvody neexistují, náklady v podobě vyšší latence, složitosti a režie často převýší přínosy.

Pro mnoho projektů proto platí: začněte s modulárním monolitem, udržujte čistou architekturu a mikroslužby zavádějte teprve tam, kde organizační nebo škálovací důvody opravdu dávají smysl.

Zdroj: https://dev.to/polliog/microservices-are-killing-your-performance-and-heres-the-math-21op

Komentáře

Odebírat
Upozornit na
guest
1 Komentář
Nejstarší
Nejnovější Nejvíce hlasů
BoneFlute

Nejsmutnější je, když i ty sporné výhody, které mikroslužby nabízejí totálně pohřbí špatné vedení.

Proč vám model napíše Python, i když jste si řekli o Rust

AI
Komentáře: 0
Výkonnostní propast mezi Pythonem a ostatními jazyky se za poslední rok a půl skoro zavřela. Dnešní modely zvládají Rust i Go srovnatelně dobře. Když jim ale volbu necháte, sáhnou stejně po Pythonu. A u knihoven je to ještě výraznější: mezi funkčně srovnatelnými balíčky je až 84procentní rozdíl v kvalitě generovaného kódu. Proč to tak je a co s tím.

WP2Shell: Kritická hrozba pro samotné jádro WordPressu. Útočníci mohou získat kontrolu nad webem

Zranitelnost ve WordPressu není žádná novinka. Kdo provozuje weby postavené na této platformě, ví, že bezpečnostní záplaty chodí prakticky pořád. O to větší pozornost by měla vzbudit chyba, u které nic z toho neplatí. A přesně takový je případ zranitelnosti, která dostala přezdívku wp2shell. potřeb. Zranitelný kontaktní formulář, děravý e-shopový plugin, opomenutá kontrola oprávnění v nějaké obskurní rozšiřující knihovně – to je denní chleba každého, kdo sleduje bezpečnostní feedy. Zpráva „nová chyba ve WordPress pluginu“ má tak nízkou informační hodnotu, že ji většina lidí přejde bez mrknutí oka.