Zpět na domů

WebFlux a virtuální vlákna: srovnání při 2000 RPS | Analýza

Analýza srovnání dvou přístupů k zpracování vysoce zatížených webových aplikací: Spring WebFlux a virtuální vlákna Project Loom. Testování při 2000 požadavcích za sekundu odhalilo klíčové rozdíly v architektuře, omezeních a praktických doporučeních pro vývojáře.

WebFlux proti virtuálním vláknům: výsledky testu na 2000 RPS
Advertisement 728x90

# 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:

Google AdInline article slot
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.

Google AdInline article slot

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:

Google AdInline article slot
  • 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

Advertisement 728x90

Číst dál