Native Kompilierung in Quarkus – warum sie wichtig ist

Hallo zusammen! Dies ist der zweite Beitrag in unserer Serie über Quarkus – heute sprechen wir über native Kompilierung.

Native Kompilierung in Quarkus – warum sie wichtig ist

Quark ist ein Java-Stack, der darauf zugeschnitten ist Kubernetes. Obwohl es hier sicherlich noch viel zu tun gibt, haben wir in vielen Aspekten gute Arbeit geleistet, einschließlich der Optimierung der JVM und einer Reihe von Frameworks. Eines der Merkmale von Quarkus, das bei Entwicklern zunehmendes Interesse geweckt hat, ist sein umfassender, nahtloser Ansatz zur Umwandlung von Java-Code in ausführbare Dateien für ein bestimmtes Betriebssystem (sogenannte „native Kompilierung“), ähnlich wie bei C und C++, wo eine solche Kompilierung erfolgt tritt normalerweise am Ende eines Zyklus aus Build, Test und Bereitstellung auf.

Und obwohl die native Kompilierung wichtig ist, wie wir weiter unten zeigen werden, sollte beachtet werden, dass Quarkus dank der Leistungsverbesserungen, die wir im gesamten Stack implementiert haben, wirklich gut auf der gängigsten Java-Maschine, OpenJDK Hotspot, läuft. Daher sollte die native Kompilierung als zusätzlicher Bonus betrachtet werden, der je nach Wunsch oder Bedarf genutzt werden kann. Tatsächlich verlässt sich Quarkus stark auf OpenJDK, wenn es um native Bilder geht. Und der Dev-Modus, der von Entwicklern sehr gut angenommen wird, sorgt aufgrund der in Hotspot implementierten erweiterten Funktionen der dynamischen Codeausführung für ein nahezu sofortiges Testen von Änderungen. Darüber hinaus werden beim Erstellen nativer GraalVM-Images die OpenJDK-Klassenbibliothek und HotSpot-Funktionen verwendet.

Warum brauchen Sie also eine native Kompilierung, wenn alles bereits perfekt optimiert ist? Wir werden versuchen, diese Frage im Folgenden zu beantworten.

Beginnen wir mit dem Offensichtlichen: Red Hat verfügt über umfassende Erfahrung in der Optimierung von JVMs, Stacks und Frameworks während der Projektentwicklung JBosseinschließlich:

  • Der erste Anwendungsserver, der in der Cloud auf der Plattform arbeitet Red Hat OpenShift.
  • Der erste Anwendungsserver zur Ausführung auf Computern PC anschließen.
  • Der erste Anwendungsserver, auf dem ausgeführt wird Raspberry Pi.
  • Eine Reihe von Projekten, die auf Geräten ausgeführt werden Android.

Wir beschäftigen uns seit vielen Jahren mit den Herausforderungen beim Ausführen von Java-Anwendungen in der Cloud und auf ressourcenbeschränkten Geräten (sprich: IoT) und haben gelernt, das Beste aus der JVM in Bezug auf Leistung und Speicheroptimierung herauszuholen. Wie viele andere beschäftigen wir uns schon seit langem mit der nativen Kompilierung von Java-Anwendungen G.C.J., Vogelgrippe, Excelsior JET und sogar Dalvik und wir sind uns der Vor- und Nachteile dieses Ansatzes durchaus bewusst (zum Beispiel das Dilemma, zwischen der Universalität von „einmal erstellen – überall ausführen“ und der Tatsache zu wählen, dass kompilierte Anwendungen kleiner sind und schneller ausgeführt werden).

Warum ist es wichtig, diese Vor- und Nachteile zu berücksichtigen? Denn in manchen Situationen wird ihr Verhältnis entscheidend:

  • Zum Beispiel in serverlosen/ereignisgesteuerten Umgebungen, in denen Dienste müssen einfach starten in (harter oder weicher) Echtzeit, um Zeit zu haben, auf Ereignisse zu reagieren. Im Gegensatz zu langlebigen persistenten Diensten erhöht hier die Dauer eines Kaltstarts die Antwortzeit auf eine Anfrage entscheidend. Der Start der JVM dauert immer noch erheblich, und obwohl dieser Zeitaufwand in einigen Fällen durch reine Hardwaremethoden reduziert werden kann, kann der Unterschied zwischen einer Sekunde und 5 Millisekunden über Leben und Tod entscheiden. Ja, hier können Sie mit der Erstellung einer Hot-Reserve von Java-Maschinen herumspielen (was wir zum Beispiel mit gemacht haben). Portierung von OpenWhisk nach Knative), aber dies allein garantiert nicht, dass genügend JVMs vorhanden sind, um Anforderungen zu verarbeiten, wenn die Last skaliert. Und aus wirtschaftlicher Sicht ist dies wahrscheinlich nicht die richtige Option.
  • Darüber hinaus taucht noch ein weiterer Aspekt häufig auf: Mandantenfähigkeit. Obwohl JVMs in ihren Fähigkeiten den Betriebssystemen sehr nahe gekommen sind, sind sie immer noch nicht in der Lage, das zu tun, was wir unter Linux so gewohnt sind – Prozesse zu isolieren. Daher kann der Ausfall eines Threads die gesamte Java-Maschine zum Absturz bringen. Viele Leute versuchen, diesen Nachteil zu umgehen, indem sie jeder Benutzeranwendung eine separate JVM zuordnen, um die Folgen eines Fehlers zu minimieren. Das ist durchaus logisch, passt aber nicht gut zur Skalierung.
  • Darüber hinaus ist für Cloud-orientierte Anwendungen ein wichtiger Indikator die Dichte der Dienste auf dem Host. Übergang zur Methodik 12 Anwendungsfaktoren, Microservices und Kubernetes erhöhen die Anzahl der Java-Maschinen pro Anwendung. Das heißt, all dies sorgt einerseits für Elastizität und Zuverlässigkeit, gleichzeitig steigt aber auch der Verbrauch an Basisspeicher im Hinblick auf den Service, und einige dieser Ausgaben sind nicht immer unbedingt notwendig. Statisch kompilierte ausführbare Dateien profitieren hier aufgrund verschiedener Optimierungstechniken, wie z. B. der Eliminierung von totem Code auf niedriger Ebene, wenn das endgültige Image nur die Teile des Frameworks (einschließlich des JDK selbst) enthält, die der Dienst tatsächlich verwendet. Daher hilft die native Kompilierung von Quarkus, Dienstinstanzen dicht auf dem Host zu platzieren, ohne die Sicherheit zu beeinträchtigen.

Tatsächlich reichen die oben genannten Argumente bereits aus, um die Berechtigung der nativen Kompilierung aus Sicht der Quarkus-Projektteilnehmer zu verstehen. Es gibt jedoch noch einen weiteren, nicht technischen, aber ebenfalls wichtigen Grund: In den letzten Jahren haben viele Programmierer und Entwicklungsunternehmen Java zugunsten neuer Programmiersprachen aufgegeben, weil sie glauben, dass Java mit seinen JVMs, Stacks und Frameworks ebenfalls geworden ist speicherhungrig, zu langsam usw.

Es besteht jedoch die Gewohnheit, jedes Problem mit demselben Tool zu lösen es ist nicht immer richtig. Manchmal ist es besser, einen Schritt zurückzutreten und nach etwas anderem zu suchen. Und wenn Quarkus die Leute zum Innehalten und Nachdenken bringt, dann ist das gut für das gesamte Java-Ökosystem. Quarkus vertritt eine innovative Sichtweise auf die Entwicklung effizienterer Anwendungen und macht Java für neue Anwendungsarchitekturen wie Serverless relevanter. Darüber hinaus wird Quarkus aufgrund seiner Erweiterbarkeit hoffentlich über ein ganzes Ökosystem von Java-Erweiterungen verfügen, wodurch die Anzahl der Frameworks, die die native Kompilierung in Anwendungen sofort unterstützen, deutlich erhöht wird.

Source: habr.com

Kommentar hinzufügen