Natívna kompilácia v Quarkus – prečo je dôležitá

Ahojte všetci! Toto je druhý príspevok v našej sérii Quarkus – dnes budeme hovoriť o natívnej kompilácii.

Natívna kompilácia v Quarkus – prečo je dôležitá

kvarkus je Java stack prispôsobený pre Kubernetes. Aj keď je tu určite oveľa viac práce, urobili sme veľa dobrej práce v mnohých aspektoch vrátane optimalizácie JVM a niekoľkých rámcov. Jednou z vlastností Quarkusu, ktorá pritiahla zvýšený záujem vývojárov, je jeho komplexný, bezproblémový prístup k premene kódu Java na spustiteľné súbory pre špecifický operačný systém (tzv. „native compilation“), podobne ako C a C++, kde takáto kompilácia sa zvyčajne vyskytuje na konci cyklu zostavovania, testovania a nasadenia.

A hoci je natívna kompilácia dôležitá, ako si ukážeme nižšie, treba poznamenať, že Quarkus beží naozaj dobre na najbežnejšom Java stroji, OpenJDK Hotspot, vďaka vylepšeniam výkonu, ktoré sme implementovali do celého zásobníka. Preto by sa natívna kompilácia mala považovať za dodatočný bonus, ktorý možno použiť podľa želania alebo potreby. V skutočnosti sa Quarkus vo veľkej miere spolieha na OpenJDK, pokiaľ ide o natívne obrázky. A vývojový režim, vrelo prijatý vývojármi, zaisťuje takmer okamžité testovanie zmien vďaka pokročilým schopnostiam dynamického spúšťania kódu implementovaným v Hotspote. Okrem toho sa pri vytváraní natívnych obrazov GraalVM využíva knižnica tried OpenJDK a možnosti HotSpot.

Prečo teda potrebujete natívnu kompiláciu, ak je už všetko dokonale optimalizované? Na túto otázku sa pokúsime odpovedať nižšie.

Začnime tým, čo je zrejmé: Red Hat má rozsiahle skúsenosti s optimalizáciou JVM, zásobníkov a rámcov počas vývoja projektu. JBoss, počítajúc do toho:

  • Prvý aplikačný server, ktorý na platforme pracuje v cloude Red Hat OpenShift.
  • Prvý aplikačný server pre beh na počítačoch Zapojte PC.
  • Prvý aplikačný server, na ktorom beží Raspberry Pi.
  • Rad projektov bežiacich na zariadeniach Android.

Problémom spúšťania Java aplikácií v cloude a na zariadeniach s obmedzenými zdrojmi (čítaj: IoT) sa venujeme už mnoho rokov a naučili sme sa z JVM vyťažiť maximum z hľadiska výkonu a optimalizácie pamäte. Ako mnohí iní, aj my dlhodobo pracujeme s natívnou kompiláciou Java aplikácií G.C.J., vtáčie, Excelsior JET a dokonca Dalvík a dobre si uvedomujeme výhody a nevýhody tohto prístupu (napríklad dilema výberu medzi univerzálnosťou „build once – run-anywhere“ a tým, že skompilované aplikácie sú menšie a bežia rýchlejšie).

Prečo je dôležité zvážiť tieto výhody a nevýhody? Pretože v niektorých situáciách sa ich pomer stáva rozhodujúcim:

  • Napríklad v prostrediach bez serverov/udalostí, kde služby jednoducho musia začať v (tvrdom alebo mäkkom) reálnom čase, aby ste mali čas reagovať na udalosti. Na rozdiel od dlhodobých trvalých služieb tu trvanie studeného štartu kriticky zvyšuje čas odozvy na požiadavku. Spustenie JVM stále trvá značné množstvo času, a hoci to možno v niektorých prípadoch znížiť čisto hardvérovými metódami, rozdiel medzi jednou sekundou a 5 milisekúndami môže byť rozdielom medzi životom a smrťou. Áno, tu sa môžete pohrať s vytvorením horúcej rezervy Java strojov (čo sme napríklad urobili s portovanie OpenWhisk do Knative), ale to samo o sebe nezaručuje, že bude dostatok JVM na spracovanie požiadaviek ako záťaž. A z ekonomického hľadiska to asi nie je tá najsprávnejšia možnosť.
  • Ďalej je tu ďalší aspekt, ktorý sa často objavuje: multiprenájom. Napriek tomu, že JVM sa svojimi schopnosťami veľmi priblížili operačným systémom, stále nie sú schopné robiť to, na čo sme v Linuxe tak zvyknutí – izolovať procesy. Zlyhanie jedného vlákna preto môže zničiť celý stroj Java. Mnoho ľudí sa snaží túto nevýhodu obísť vyhradením samostatného JVM pre aplikácie každého používateľa, aby sa minimalizovali následky zlyhania. To je celkom logické, ale nehodí sa to k škálovaniu.
  • Pre cloudové aplikácie je navyše dôležitým ukazovateľom hustota služieb na hostiteľovi. Prechod na metodiku 12 aplikačných faktorov, mikroslužby a Kubernetes zvyšujú počet Java strojov na aplikáciu. To všetko na jednej strane poskytuje elasticitu a spoľahlivosť, ale zároveň sa zvyšuje aj spotreba základnej pamäte z hľadiska obsluhy a niektoré z týchto výdavkov nie sú vždy nevyhnutne potrebné. Staticky skompilované spustiteľné súbory tu profitujú vďaka rôznym optimalizačným technikám, ako je napríklad eliminácia mŕtveho kódu na nízkej úrovni, keď konečný obrázok obsahuje iba tie časti rámcov (vrátane samotného JDK), ktoré služba skutočne používa. Preto natívna kompilácia Quarkus pomáha husto umiestniť inštancie služieb na hostiteľa bez ohrozenia bezpečnosti.

V skutočnosti už vyššie uvedené argumenty stačia na to, aby sme pochopili opodstatnenosť natívnej kompilácie z pohľadu účastníkov projektu Quarkus. Existuje však aj iný, netechnický, ale tiež dôležitý dôvod: v posledných rokoch mnoho programátorov a vývojárskych spoločností opustilo Javu v prospech nových programovacích jazykov, pretože verili, že Java sa spolu so svojimi JVM, zásobníkmi a frameworkami stala príliš pamäťové, príliš pomalé atď.

Zvyk používať rovnaký nástroj na riešenie akéhokoľvek problému však je nie je to vždy správne. Niekedy je lepšie urobiť krok späť a hľadať niečo iné. A ak Quarkus prinúti ľudí zastaviť sa a zamyslieť sa, potom je to dobré pre celý ekosystém Java. Quarkus predstavuje inovatívny pohľad na to, ako vytvárať efektívnejšie aplikácie, vďaka čomu je Java relevantnejšia pre nové aplikačné architektúry, ako je bezserver. Navyše, vďaka svojej rozšíriteľnosti bude mať Quarkus, dúfajme, celý ekosystém rozšírení Java, čím sa výrazne zvýši počet rámcov, ktoré budú podporovať natívnu kompiláciu v aplikáciách hneď po vybalení.

Zdroj: hab.com

Pridať komentár