# WebFlux versus virtuální vlákna: porovnání při zátěži 2000 požadavků za sekundu
Při vysokých zátěžích volba mezi reaktivním modelem Spring WebFlux a novou paradigmou virtuálních vláken Project Loom určuje výkon a škálovatelnost Java aplikací. Toto studium představuje výsledky zátěžového testování dvou přístupů při intenzitě 2000 požadavků za sekundu na výukovém projektu mikroslužeb.
Architektura Spring WebFlux: cyklus událostí a neblokující vstup-výstup
Spring WebFlux využívá neblokující model vstupu-výstupu s cyklem událostí (event loop). Na rozdíl od tradičního modelu „jeden požadavek — jedno vlákno“ WebFlux zpracovává tisíce spojení malým počtem vláken. Klíčový princip: vlákno se při čekání na vstup-výstup neblokuje, ale zaregistruje zájem o událost (např. „příjely data na socket“) a přepne se na jiné úlohy.
Centrální součástí je Netty, který se ve WebFlux používá ve výchozím nastavení. Netty spravuje event loop prostřednictvím EventLoopGroup. Počet vláken cyklu událostí se určuje podle vzorce:
int DEFAULT_IO_WORKER_COUNT = Integer.parseInt(System.getProperty(
ReactorNetty.IO_WORKER_COUNT,
"" + Math.max(Runtime.getRuntime().availableProcessors(), 4)));
Tedy počet vláken odpovídá počtu dostupných procesorů, ale ne méně než 4. V kontejnerovém prostředí lze tuto hodnotu upravit tak, aby odpovídala přiděleným zdrojům.
Každé síťové spojení (Channel) je vázáno na konkrétní event loop (channel affinity). To zajišťuje absence synchronizace a efektivitu procesorové mezipaměti. Nicméně jakákoli blokující operace v event loop zastaví zpracování všech spojení přiřazených k tomuto cyklu.
Virtuální vlákna: princip fungování Project Loom
Virtuální vlákna zachovávají model „jeden požadavek — jedno vlákno“, ale výrazně snižují režii. Každý požadavek dostane své virtuální vlákno, které se montuje na carrier-vlákna (platformová vlákna). Carrier-vlákna spravuje plánovač na bázi ForkJoinPool.
Počet carrier-vláken ve výchozím nastavení odpovídá počtu dostupných procesorů. Například v kontejneru se 2 CPU bude 2 carrier-vlákna, na kterých mohou běžet tisíce virtuálních vláken.
Metoda vytvoření výchozího plánovače:
private static ForkJoinPool createDefaultScheduler() {
ForkJoinWorkerThreadFactory factory = pool -> new CarrierThread(pool);
int parallelism, maxPoolSize, minRunnable;
String parallelismValue = System.getProperty("jdk.virtualThreadScheduler.parallelism");
String maxPoolSiz
Výhody virtuálních vláken:
- Zachování imperativního stylu programování
- Čitelné stack trace
- Podpora ThreadLocal
- Zjednodušení práce se stávajícími blokujícími knihovnami
Výsledky testování při 2000 požadavcích za sekundu
Během testování výukového projektu mikroslužeb byly zjištěny následující vlastnosti:
- WebFlux prokázal stabilní výkon za předpokladu absence blokujících operací v event loop. Při integraci s blokujícími knihovnami (např. JDBC) však bylo nutné tyto operace vyvést do samostatného poolu vláken (Schedulers.boundedElastic()), což přidávalo složitost.
- Virtuální vlákna prokázala zjednodušení vývoje a ladění při zachování vysokého výkonu. Při 2000 požadavcích za sekundu použití virtuálních vláken na Spring MVC a Tomcat nezaostávalo za WebFlux z hlediska propustnosti, přičemž kód zůstal obvyklý pro většinu Java vývojářů.
Kritickým faktorem pro WebFlux se ukázalo správné použití reaktivních řetězců a vyhýbání se blokujícím voláním v event loop. Pro virtuální vlákna je důležité brát v úvahu, že neřeší problém CPU-bound operací — při vysoké zátěži na procesor může vzniknout konkurence o carrier-vlákna.
Kritické rozdíly a doporučení pro výběr
Při výběru mezi WebFlux a virtuálními vlákny zohledněte následující aspekty:
- Typ zátěže:
- Pro I/O-bound aplikace (mnoho čekání na vstup-výstup) jsou oba přístupy efektivní
- Pro CPU-bound úlohy mohou virtuální vlákna zaostávat kvůli konkurenci o carrier-vlákna
- Ekosystém knihoven:
- Pokud projekt intenzivně využívá blokující knihovny (JDBC), přechod na virtuální vlákna zjednoduší migraci
- Pro nové projekty s podporou reaktivních ovladačů (R2DBC) zůstává WebFlux variantou
- Kvalifikace týmu:
- Reaktivní programování vyžaduje hluboké porozumění asynchronním vzorům
- Virtuální vlákna umožňují použití obvyklého imperativního stylu
Co je důležité
- Výkon při 2000 požadavcích za sekundu: Oba přístupy zvládnou zátěž, ale virtuální vlákna zjednodušují vývoj díky zachování imperativního stylu
- Kritická omezení: V WebFlux blokující operace v event loop paralyzuje všechny požadavky na tomto cyklu; virtuální vlákna neřeší problémy CPU-bound operací
- Ekosystém: Přechod na WebFlux vyžaduje nahrazení blokujících knihoven reaktivními ekvivalenty, což může být nákladné
- Ladění: Reaktivní aplikace jsou složitější na diagnostiku kvůli nečitelným stack trace, zatímco virtuální vlákna poskytují obvyklé nástroje profilování
— Editorial Team
Zatím žádné komentáře.