Ahoj všichni! Dnes máme na pořadu druhý příspěvek z naší série o Quarkus – budeme hovořit o nativní kompilaci.

– je to Java stack zaměřený na . A i když je zde samozřejmě ještě spousta práce, podařilo se nám dobře zpracovat mnoho aspektů, včetně optimalizace JVM a řady frameworků. Jednou z vlastností Quarkus, která vyvolala zvýšený zájem mezi vývojáři, je komplexní bezproblémový přístup k přetváření Java kódu na spustitelné soubory pro konkrétní operační systém (tzv. „nativní kompilace“) podle vzoru C a C++, kde se taková kompilace obvykle provádí na konci cyklu skládajícího se ze sestavení, testování a nasazení.
I když je nativní kompilace, jak ukážeme níže, důležitá, je třeba poznamenat, že Quarkus skutečně dobře funguje i na běžné Java platformě OpenJDK Hotspot díky těm výkonovým vylepšením, která jsme implementovali po celém stacku. Proto by se na nativní kompilaci mělo pohlížet jako na další bonus, který lze využít podle potřeby. Ve skutečnosti, pokud jde o nativní obrazy, Quarkus se značně opírá o OpenJDK. A vysoce hodnocený vývojový režim dev mode umožňuje prakticky okamžité testování změn díky vyspělým možnostem dynamického provádění kódu, které jsou implementovány v Hotspot. Kromě toho při vytváření nativních obrazů využívá GraalVM knihovnu tříd OpenJDK a schopnosti HotSpot.
Proč tedy potřebujeme nativní kompilaci, pokud je vše už tak dobře optimalizováno? Na tuto otázku se pokusíme odpovědět níže.
Začněme s jasným: Red Hat má bohaté zkušenosti s optimalizací JVM, stacků a frameworků v průběhu vývoje projektu , včetně:
- První aplikace serveru pro práci v cloudu na platformě .
- První aplikace serveru pro práci na počítačích .
- První aplikace serveru pro práci na .
- Celý řadu projektů, které fungují na zařízeních .
Jsme už mnoho let aktivní v oblasti spuštění Java aplikací v cloudu a na zařízeních s omezenými zdroji (čti, IoT) a naučili jsme se vytěžit z JVM maximum, pokud jde o výkon a optimalizaci paměti. Jako mnoho dalších už dlouho pracujeme s nativní kompilací Java aplikací přes , , a dokonce a skvěle si uvědomujeme výhody a nevýhody takového přístupu (například dilema výběru mezi univerzálností "build once – run-anywhere" a tím, že zkompilované aplikace mají menší velikost a spouštějí se rychleji).
Proč je tak důležité brát tyto výhody a nevýhody v úvahu? Protože v některých situacích se jejich poměr stává rozhodujícím:
- Například v serverless/událostmi řízených prostředích, kde v reálném čase (tvrdém nebo měkkém), aby stihly reagovat na události. Na rozdíl od dlouho žijících persistentních služeb, zde související doba studeného startu kriticky zvyšuje dobu odezvy na požadavek. Na spuštění JVM stále ubíhá značné množství času a i když lze v některých případech čas zkrátit čistě hardwarovými metodami, rozdíl mezi jednou sekundou a 5 milisekundami může být otázkou života a smrti. Ano, zde lze experimentovat s vytvořením teplé rezervy Java strojů (což jsme například udělali při ), ale samo o sobě to nezaručuje dostatečný počet JVM potřebný k zpracování požadavků při zvyšování zátěže. Ekonomicky vzato to určitě není ten nejlepší scénář.
- Dále existuje také často se objevující aspekt, jako je multitenantnost. I když se JVM svými schopnostmi značně přiblížily operačním systémům, stále nejsou schopny dělat to, na co jsme si tak zvykli v Linuxu – izolovat procesy. Proto selhání jednoho vlákna může vyřadit celou Java mašinu. Mnozí se snaží tento nedostatek obejít tím, že přidělují každému uživatelskému aplikaci samostatnou JVM, aby minimalizovali důsledky selhání. To dává smysl, ale špatně se to spojuje se škálovatelností.
- Kromě toho je pro cloudově orientované aplikace důležitým ukazatelem také hustota služeb na hostiteli. Přechod na metodologii , mikroslužby a Kubernetes zvyšují počet Java instancí pro jednu aplikaci. To znamená, že na jedné straně to poskytuje flexibilitu a spolehlivost, ale zároveň roste i spotřeba základní paměti na službu, přičemž část těchto výdajů není vždy zcela nezbytná. Staticky kompilované spustitelné soubory zde získávají výhodu pomocí různých optimalizačních technik, jako je nízkoúrovňová eliminace mrtvého kódu, kdy do konečného obrazu jsou zahrnuty pouze ty části frameworků (včetně JDK), které služba skutečně využívá. Proto nativní kompilace Quarkus pomáhá efektivněji umisťovat instance služeb na hostiteli bez ztráty bezpečnosti.
Vlastně, výše uvedené argumenty už stačí k tomu, abychom pochopili opodstatněnost nativní kompilace z pohledu účastníků projektu Quarkus. Existuje však ještě jeden, netechnický, ale také důležitý důvod: v posledních letech se mnoho programátorů a vývojářských společností vzdalo Javy ve prospěch nových programovacích jazyků, protože usoudili, že Java spolu se svými JVM, stacky a frameworky se stala příliš náročnou na paměť, příliš pomalou atd.
Nicméně zvyknout si používat stejný nástroj pro řešení všech úkolů – Někdy je lepší udělat krok zpět a hledat něco jiného. A pokud Quarkus nutí lidi na chvíli zastavit a zamyslet se, pak je to dobré pro celý ekosystém Javy. Quarkus představuje inovativní pohled na to, jak vytvářet efektivnější aplikace, čímž činí Javu relevantnější pro nové architektury aplikací, jako je serverless. Dále, díky své rozšiřitelnosti, Quarkus, jak doufáme, získá celou ekosystém Java rozšíření, což výrazně zvýší počet frameworků, které z krabice budou podporovat nativní kompilaci v rámci aplikací.
Zdroj: habr.com
