Quarkus - Ein neuer Blick auf Cloud Native Java

Hallo habr

Im kommenden neuen Jahr planen wir die ernsthafte Entwicklung der Containerthemen Cloud-Native Java und Kubernetes . Eine logische Fortsetzung dieser Themen auf Russisch wird die Geschichte über das Quarkus- Framework sein, die bereits in einem guten Artikel über Habré behandelt wurde. Der heutige Artikel befasst sich weniger mit dem " subatomaren ultraschnellen Java- Gerät" als vielmehr mit den Perspektiven, die Quarkus für Enterprise bietet.

Java und die JVM sind nach wie vor äußerst beliebt. Bei der Arbeit mit serverlosen Technologien und cloudorientierten Mikrodiensten werden Java und andere Sprachen für die JVM immer seltener verwendet, da sie zu viel Speicherplatz beanspruchen und zu langsam geladen werden, was sie für ungeeignet macht Verwendung mit kurzlebigen Behältern. Glücklicherweise ändert sich diese Situation derzeit dank Quarkus.

Einleitung


Je mehr ich DevOps, Container und serverlose Technologien verwende, desto mehr schreibe ich meinen containerisierten Code in Lightweight-Containern oder FaaS in Python oder JavaScript. Java ist einfach zu schwer zu booten , um in einem serverlosen Framework verwendet zu werden. In Bezug auf Microservices bieten JavaScript oder Python ein schnelleres Laden und kompaktere Container, wodurch Java effizienter wird.



Python und JavaScript sind die besten Sprachen für die Erstellung cloudbasierter Microservices

Java ist mehr als 20 Jahre alt und zum Zeitpunkt seiner Gründung war die Welt völlig anders als heute. Mit dem Aufkommen der JVM wurden große Probleme behoben - wir konnten Code einmal schreiben und auf vielen Plattformen und Betriebssystemen ausführen. Mit Containern können Sie Anwendungen, Bibliotheken und Betriebssystemressourcen in separate Container packen, und jeder dieser Container kann überall verwendet werden. Die von JVM bereitgestellte Portabilität ist jetzt weniger relevant . Früher waren wir bereit, zusätzliche Kosten zu verursachen, um die Portabilität zu gewährleisten. Jetzt sind diese Zeiten vorbei. Jetzt müssen Sie schnell mit minimalen Verzögerungen und reaktiven Anwendungen arbeiten, die immer verfügbar sind . Container und Container-Orchestrierungs-Tools wie Kubernetes bieten diese Funktionen unabhängig von der Programmiersprache.

Unternehmen, die auf Microservice-Architekturen umsteigen, verwenden ihre in Java geschriebenen Spring- basierten Services, verknüpfen sie mit umfangreichen JAR-Archiven, fügen JDKs hinzu und führen sie in einem Linux-basierten Container aus. Diese Lösung funktioniert, Sie müssen sich jedoch mit schweren Containern mit einer Größe von 500 MB befassen, die jeweils 10 bis 30 Sekunden lang in einen barrierefreien Zustand versetzt werden. Das ist ein ernstes Problem. Nach der Migration stellen viele Unternehmen langsam auf Python um, lassen die serverseitigen Dienste in Java und beenden letztendlich FaaS.

Serverlose Technologien und FaaS sind heutzutage sehr beliebt, da Sie sich auf das Schreiben von Funktionen konzentrieren können, ohne sich um die Infrastruktur kümmern zu müssen. Wie auch immer, sie arbeiten alle in Containern, aber der Cloud-Anbieter verwaltet ihren Lebenszyklus. Das Beste daran ist, dass der Anbieter nach einer bestimmten Zeit den Container vollständig stoppt und seine Arbeit erst nach dem nächsten Anruf wieder aufnimmt, dh Sie zahlen nur für die tatsächliche Arbeitszeit. Der erste Funktionsaufruf kann etwas länger dauern als üblich, dies ist der berühmte Kaltstart . Tatsache ist, dass der Container primär beladen werden muss. Die Verwendung von Python oder JavaScript ist kein so großes Problem, aber im Fall von Java kann das erstmalige Laden 10 bis 15 Sekunden dauern. Dies ist ein Satz und einer der Gründe für den Rückgang der Beliebtheit von Java. Jetzt brauchen wir einen Code, der gestartet, die Aufgabe abgeschlossen und dann beendet werden kann . Wir möchten nicht mit vielen Threads oder lang laufenden Prozessen fertig werden, sondern benötigen kurzlebige Prozesse, die sehr schnell geladen werden können .

Quarkus stellt sich vor


Wenn Sie technische Blogs lesen oder den Nachrichten folgen, denken Sie wahrscheinlich, dass das serverlose Paradigma die Welt erobert , und jeder nimmt es mit äußerster Begeisterung auf. Jetzt kann ein Startup Funktionen schreiben und - dank der Verwendung von JavaScript - in der Cloud als Service bereitstellen und sie auch skalieren, um Millionen von Benutzern zu unterstützen, ohne die Infrastruktur verwalten zu müssen. Es stimmt, es gibt auch eine reale Welt außerhalb des Silicon Valley: Finanzinstitute, Behörden, Einzelhandel und viele andere Branchen, die mit Millionen von Java-Leitungen bedient werden, deren Neuschreibung zu teuer ist. Wir müssen daher davon ausgehen, dass in diesen Branchen weiterhin schwere Container eingesetzt werden müssen.



GraalVM und insbesondere Substrate VM öffnen heute die Tür für die glorreiche und langfristige Zukunft der Java-Sprache. GraalVM ist eine universelle virtuelle Maschine zum Ausführen von Anwendungen, die in JavaScript, Python, Ruby, R und Sprachen für die JVM geschrieben wurden, insbesondere Java, Scala oder Kotlin. Das Coolste ist, dass Sie mit GraalVM (im AOT-Modus) Programme in eine native ausführbare Datei vorkompilieren können . Dies bedeutet, dass Sie Ihren Java-Code direkt in maschinenspezifischen Code übersetzen können. Das resultierende Programm funktioniert nicht auf Java HotSpot VM, sondern verwendet alle erforderlichen Komponenten, insbesondere die Speicherverwaltung und die Thread-Planung aus einer anderen Implementierung einer virtuellen Maschine namens Substrate VM. Die Substrate-VM ist in Java geschrieben und ihr Code wird in eine native ausführbare Datei kompiliert. Das resultierende Programm startet schneller und verursacht dementsprechend einen geringeren Overhead bei der Speichernutzung im Vergleich zu Java VM. Das ist großartig, aber Sie denken wahrscheinlich: Frühes Kompilieren? Dies widerspricht der Grundidee, für die die JVM erstellt wurde, dh die Verwendung von einmal geschriebenem Code überall! Das ist verrückt !!! Denken Sie jedoch selbst: Jetzt haben wir Container, für die keine JVM erforderlich ist. Konventionelle Containeranwendungen, die mit Spring Boot erstellt wurden, verfügen über eine zusätzliche Abstraktionsebene, die in der Welt von Kubernetes absolut unnötig ist . Auf der JVM im Container wird eine Java-Anwendung ausgeführt. Dieser Container bleibt unverändert, da das fertige Produkt heute ein Container und keine Anwendung ist. Jetzt packen wir Container, keine WAR-Dateien. Daher werden alle mit der Verwendung der JVM-Anwendung im Container verbundenen Kosten unbrauchbar , und AOT wird zu einer sehr logischen Entscheidung, wenn Sie Ihre Anwendungen in Container packen.

Richtig, die AOT-Kompilierung schränkt die dynamischen Fähigkeiten von Java erheblich ein (Laden von Klassen zur Laufzeit, Reflektion, Proxies usw.). In der Praxis bedeutet dies, dass 90% des Java-Ökosystems nicht unverändert funktionieren. Dementsprechend muss sich das Java-Ökosystem anpassen . Es gibt gute Nachrichten: Das meiste kann während der Montage gemacht werden!

Das ist die Kraft von Quarkus. Es verwendet GraalVM und stellt ein Ökosystem bereit, das die AOT-Kompilierung zum Zeitpunkt der Erstellung unterstützt. Auf diese Weise können Sie mit Java native Binärdateien erstellen. Dank Quarkus wird GraalVM Java-Entwicklern zur Verfügung gestellt .

Erste Schritte mit Quarkus


Wie oben erläutert, stellt Quarkus eine frühe Kompilierung für Java-Anwendungen bereit, und dies erzeugt ein Ökosystem mit subatomarem Überschall-Java. Quarkus zeichnet sich durch ultraschnelles Laden aus - und Java kehrt auf dem Gebiet der cloudbasierten Entwicklung zum Spiel zurück. Seit Jahren hat mich keine neue Technologie inspiriert - und damit bin ich nicht allein .

Lesen Sie den Anfängerleitfaden - und überzeugen Sie sich selbst. Es gibt immer noch viele Unternehmen, die Java + JPA im Container verwenden, aber in dieser Konfiguration kann das Laden 15 Sekunden dauern, und im Fall von Quarkus 0,005!



Quarkus Stats

Sie verwenden dieselbe IDE und dieselben Tools wie in der Spring Boot-Welt. Verwenden Sie zum Erstellen Ihres Projekts Maven oder Gradle. Das Projekt kann direkt in der IDE ausgeführt werden. Darüber hinaus ist ein Hot-Live-Neustart für alle Änderungen verfügbar, und Sie müssen die Anwendung nicht neu starten. Quarkus ist nicht Spring. Wenn Sie also Spring Boot verwenden, müssen Sie Spring-spezifischen Code migrieren. Glücklicherweise bietet Quarkus eine gewisse Kompatibilität für die Implementierung von Spring-Abhängigkeiten , was die Arbeit erheblich vereinfacht. Das Quarkus-Framework ist standardkonform, was eine einfache Portierung und Unterstützung des Codes bedeutet.

Quarkus-Entwicklungsprozess


Quarkus kann im Entwicklungsmodus verwendet werden, der an Spring Boot erinnert. Damit können Sie Ihr Projekt auch in ein dickes Glas packen. Dies ist sehr praktisch zum Testen und Debuggen Ihres Codes, da ein Neustart in Echtzeit unterstützt wird. Sie müssen jedoch im Voraus kompilieren, um in die Produktion zu gelangen. Der gesamte Prozess ist in der folgenden Abbildung dargestellt:



  • Erstellen Sie die Anwendung zunächst in Ihrer bevorzugten IDE, und führen Sie sie dann im Entwicklermodus aus: „ mvnw compile quarkus:dev “ (wie bei einer Spring Boot-Anwendung). Sie können es auch in ein dickes Glas packen.
  • Sobald Sie den vorherigen Schritt abgeschlossen haben und das Ergebnis zu Ihnen passt, können Sie die Java-Binärdatei erstellen. Führen Sie mvnw package -Pnative : „ mvnw package -Pnative “. Dies wird einige Zeit in Anspruch nehmen, da der native Code bei der Kompilierung im Voraus generiert wird! Wenn dieser Schritt abgeschlossen ist, steht Ihnen eine ultrakleine und ultraschnelle ausführbare Datei zur Verfügung, die jedoch nur auf Ihrer Plattform / Ihrem Betriebssystem funktioniert, dh nicht portiert wird! Das ist aber normal, da wir es in einen Container packen können - und so die Portabilität gewährleisten. ./mvnw package -Pnative -Dnative-image.docker-build=true : ./mvnw package -Pnative -Dnative-image.docker-build=true 4 - und wir entfernen die ausführbare Datei aus dem Docker-Container. Das heißt, wir führen eine native Assembly innerhalb des Containers durch und erstellen eine Binärdatei. Diese Technik funktioniert möglicherweise nicht auf Ihrem Laptop, wenn sich das Betriebssystem von der Zielplattform unterscheidet, die in der DockerFile die von Quarkus während der Erstellung des Projekts generiert wurde.
  • Nachdem Sie die Binärdatei erstellt haben, erstellen Sie einfach ein Image basierend auf der Docker-Datei. docker build -f src/main/docker/Dockerfile.native -t quarkus-quickstart/quickstart .
  • Schließlich kann die Anwendung in Docker oder Kubernetes gestartet werden: docker run -i --rm -p 8080:8080 quarkus-quickstart/quickstart

Quarkus Funktionen


Quarkus bietet viel mehr Funktionen als nativer Java-Code.

  • Vereinheitlichung der imperativen und reaktiven Funktionen: Ermöglicht die Kombination von vertrautem imperativem Code mit nicht blockierendem Code, der in einem reaktiven Stil geschrieben ist.
  • Der Entwickler ist erfreut : einheitliche Konfiguration, Zero Config, sofortiger Live-Neustart, optimierter optimierter Code für 80% der gängigen Fälle und flexibler Code für die restlichen 20% der Fälle, Generierung von nativen ausführbaren Dateien ohne Aufwand, Live-Codierung.
  • Erstaunlich schnelles Laden, ein unglaublich kleiner residenter Speicherbereich (ja, es geht nicht nur um die Größe des Heapspeichers!), Der bei der Orchestrierung von Containern auf Plattformen wie Kubernetes eine fast sofortige vertikale Skalierung und eine sehr hohe Speichernutzung ermöglicht. Weitere Details .
  • Quarkus bietet ein ganzheitliches, benutzerfreundliches Full-Stack-Framework mit erstklassigen Bibliotheken, die Sie kennen und lieben und die in die unterstützenden Strukturen eingebettet sind. Weitere Details .
  • Bibliotheken für Ruhezustand, JPA, REST, JWT usw. werden unterstützt.
  • Unterstützte Konfigurationen, die in Kubernetes und OpenShift bereitgestellt werden
  • Öffnen Sie die Ablaufverfolgung mit Jaeger
  • Kotlin- Unterstützung
  • Messaging mit Kafka, Camel ...
  • Schauen Sie sich auch die Liste der Erweiterungen an !

Quarkus-Ökosystem


Kurz gesagt, Sie können jetzt herkömmliche JPA / JTA-Transaktionsdienste in superschnellen, leichten Containern ausführen - sowohl in der Cloud als auch vor Ort .

Quarkus-Beispiel


In diesem Abschnitt werfen wir einen vereinfachten Blick auf den Einsteigerleitfaden, um Ihnen einen Eindruck von der Leistungsfähigkeit von Quarkus zu vermitteln.



Am einfachsten erstellen Sie ein neues Quarkus-Projekt, indem Sie ein Eingabeaufforderungsfenster öffnen und den folgenden Befehl ausführen:

 mvn io.quarkus:quarkus-maven-plugin:0.12.0:create \ -DprojectGroupId=org.acme \ -DprojectArtifactId=getting-started \ -DclassName="org.acme.quickstart.GreetingResource" \ -Dpath="/hello" 

Dadurch wird ein Maven-Projekt generiert, bei dem GreetingResuce den Endpunkt / Hallo bereitstellt. Dockerfile-Docker-Images für native Dateien und JVM (traditionelle Images in Form eines dicken JAR) werden ebenfalls generiert. Der Code ist sehr sauber und einfach:

 @Path("/hello") public class GreetingResource { @GET @Produces(MediaType.TEXT_PLAIN) public String hello() { return "hello"; } } 

Verwenden ./mvnw compile quarkus:dev zum Ausführen der Anwendung: ./mvnw compile quarkus:dev
Die Anwendung wird mit dem Paket ./mvnw gepackt. Das Ergebnis sind 2 JAR-Dateien:

  • getting-started-1.0-SNAPSHOT.jar - enthält nur Klassen und Projektressourcen. Dies ist ein häufiges Artefakt, das aus der Versammlung von Maven resultiert.
  • getting-started-1.0-SNAPSHOT-runner.jar ist eine ausführbare jar. Beachten Sie, dass dies nicht "uber-jar" ist, es gibt Abhängigkeiten hier, sie werden in das Zielverzeichnis / lib kopiert.

Sie können die Anwendung mit folgendem Befehl starten: java -jar target / getting-started-1.0-SNAPSHOT-runner.jar

Anschließend müssen Sie GraalVM herunterladen und installieren und die Umgebungsvariable GRAALVM_HOME .

Jetzt können Sie eine native ausführbare Datei erstellen mit: ./mvnw package -Pnative -Dnative-image.docker-build=true .

So erstellen Sie ein Docker-Image: docker build -f src/main/docker/Dockerfile.native -t quarkus-quickstart/quickstart .

Jetzt kann es mit jeder Container-Orchestrierungs-Engine gestartet werden, wenn Sie minishift verwenden :

 kubectl run quarkus-quickstart --image=quarkus-quickstart/quickstart:latest --port=8080 --image-pull-policy=IfNotPresent 

 kubectl expose deployment quarkus-quickstart --type=NodePort 

Das ist alles!; Jetzt haben Sie einen Container mit einem Java-REST-Service, der in 0,004 Sekunden startet!

Fazit


Jetzt verstehe ich, warum ich von dem von Red Hat unterstützten Quarkus-Framework so beeindruckt bin. Ich bin fest davon überzeugt, dass dies die technologische Landschaft von Java verändern und großen traditionellen Unternehmen eine echte Möglichkeit bieten wird, in die Cloud zu migrieren.

Kubernetes + Knative + Quarkus ändern die Spielregeln in einer Cloud-orientierten Entwicklung und werden jedem Java-Entwickler gefallen.

Dieses Repository enthält viele interessante Beispiele!

Source: https://habr.com/ru/post/de482968/


All Articles