Nativní kompilace v Quarkus – proč je důležitá

Ahoj všichni! Toto je druhý příspěvek v naší sérii o Quarkusu – dnes budeme hovořit o nativní kompilaci.

Nativní kompilace v Quarkus – proč je důležitá

kvarkus je Java stack přizpůsobený pro Kubernetes. I když je zde určitě mnohem více práce, udělali jsme spoustu dobré práce na mnoha aspektech, včetně optimalizace JVM a řady rámců. Jednou z vlastností Quarkusu, která přilákala zvýšený zájem vývojářů, je jeho komplexní, bezproblémový přístup k přeměně kódu Java na spustitelné soubory pro konkrétní operační systém (tzv. „nativní kompilace“), podobně jako C a C++, kde taková kompilace se obvykle vyskytuje na konci cyklu sestavení, testování a nasazení.

A i když je nativní kompilace důležitá, jak si ukážeme níže, je třeba poznamenat, že Quarkus běží opravdu dobře na nejběžnějším Java stroji, OpenJDK Hotspot, díky vylepšením výkonu, která jsme implementovali do celého zásobníku. Nativní kompilace by proto měla být považována za dodatečný bonus, který lze použít podle potřeby nebo potřeby. Ve skutečnosti Quarkus hodně spoléhá na OpenJDK, pokud jde o nativní obrázky. A vývojářský režim, vřele přijatý vývojáři, zajišťuje téměř okamžité testování změn díky pokročilým schopnostem dynamického spouštění kódu implementovaným v Hotspotu. Kromě toho se při vytváření nativních obrazů GraalVM využívá knihovna tříd OpenJDK a schopnosti HotSpot.

Proč tedy potřebujete nativní kompilaci, když je již vše dokonale optimalizováno? Na tuto otázku se pokusíme odpovědět níže.

Začněme tím, co je zřejmé: Red Hat má rozsáhlé zkušenosti s optimalizací JVM, zásobníků a rámců během vývoje projektu JBoss, jako:

  • První aplikační server, který na platformě pracuje v cloudu Red Hat OpenShift.
  • První aplikační server pro běh na počítačích Zapojte PC.
  • První aplikační server, na kterém běží Raspberry Pi.
  • Řada projektů běžících na zařízeních Android.

Již mnoho let se zabýváme problémy s provozováním Java aplikací v cloudu a na zařízeních s omezenými zdroji (čti: IoT) a naučili jsme se z JVM vytěžit maximum z hlediska optimalizace výkonu a paměti. Jako mnoho dalších pracujeme s nativní kompilací Java aplikací již delší dobu G.C.J., Avian, Excelsior JET a dokonce i Dalvik a dobře si uvědomujeme klady a zápory tohoto přístupu (například dilema volby mezi univerzálností „sestavit jednou – spustit-každé“ a tím, že kompilované aplikace jsou menší a běží rychleji).

Proč je důležité zvážit tato pro a proti? Protože v některých situacích se jejich poměr stává rozhodujícím:

  • Například v prostředích bez serveru/událostí, kde služby prostě musí začít v (tvrdém nebo měkkém) reálném čase, abyste měli čas reagovat na události. Na rozdíl od dlouhodobých perzistentních služeb zde trvání studeného startu kriticky prodlužuje dobu odezvy na požadavek. Spuštění JVM stále trvá značné množství času, a i když to lze v některých případech snížit čistě hardwarovými metodami, rozdíl mezi jednou sekundou a 5 milisekundami může být rozdílem mezi životem a smrtí. Ano, zde si můžete pohrát s vytvořením horké rezervy Java strojů (což jsme například udělali s portování OpenWhisk do Knative), ale to samo o sobě nezaručuje, že bude dostatek JVM ke zpracování požadavků jako zátěž. A z ekonomického hlediska to asi není ta nejsprávnější varianta.
  • Dále je tu další aspekt, který se často objevuje: vícenájem. Navzdory tomu, že se JVM svými schopnostmi velmi přiblížily operačním systémům, stále nejsou schopny dělat to, na co jsme v Linuxu tak zvyklí – izolovat procesy. Selhání jednoho vlákna tedy může zničit celý stroj Java. Mnoho lidí se snaží tuto nevýhodu obejít tím, že pro každou uživatelskou aplikaci vyhradí samostatný JVM, aby se minimalizovaly následky selhání. To je celkem logické, ale nesedí to dobře se škálováním.
  • U cloudově orientovaných aplikací je navíc důležitým ukazatelem hustota služeb na hostiteli. Přechod k metodice 12 aplikačních faktorů, mikroslužby a Kubernetes zvyšují počet Java strojů na aplikaci. To vše na jedné straně poskytuje elasticitu a spolehlivost, ale zároveň se také zvyšuje spotřeba základní paměti z hlediska obsluhy a některé z těchto výdajů nejsou vždy nezbytně nutné. Staticky kompilované spustitelné soubory zde těží díky různým optimalizačním technikám, jako je eliminace mrtvého kódu na nízké úrovni, kdy finální obraz zahrnuje pouze ty části frameworků (včetně samotného JDK), které služba skutečně používá. Nativní kompilace Quarkus proto pomáhá hustě umístit instance služeb na hostitele, aniž by došlo k ohrožení bezpečnosti.

Ve skutečnosti výše uvedené argumenty již stačí k pochopení oprávněnosti nativní kompilace z pohledu účastníků projektu Quarkus. Existuje však další, netechnický, ale také důležitý důvod: v posledních letech mnoho programátorů a vývojářských společností opustilo Javu ve prospěch nových programovacích jazyků v domnění, že Java se spolu se svými JVM, stacky a frameworky stala příliš náročné na paměť, příliš pomalé atd.

Zvyk používat stejný nástroj k řešení jakéhokoli problému však je není to vždy správné. Někdy je lepší udělat krok zpět a hledat něco jiného. A pokud Quarkus přiměje lidi zastavit se a přemýšlet, pak je to dobré pro celý ekosystém Java. Quarkus představuje inovativní pohled na to, jak vytvářet efektivnější aplikace, díky čemuž je Java relevantnější pro nové aplikační architektury, jako je bezserver. Navíc díky své rozšiřitelnosti bude mít Quarkus snad celý ekosystém Java rozšíření, čímž se výrazně zvýší počet frameworků, které budou podporovat nativní kompilaci v aplikacích hned po vybalení.

Zdroj: www.habr.com

Přidat komentář