Quarkus - Un nouveau regard sur Java Native Cloud

Bonjour, Habr!

Au cours de la nouvelle année à venir, nous prévoyons de développer sérieusement des thèmes de conteneurs, Cloud-Native Java et Kubernetes . Une suite logique de ces sujets en russe sera l'histoire du cadre Quarkus , déjà considérée dans un bon article sur Habré. L'article d'aujourd'hui ne se concentre pas tant sur le «périphérique Java ultrarapide subatomique » que sur les perspectives que Quarkus apporte à Enterprise.

Java et la JVM sont toujours extrêmement populaires, mais lorsque vous travaillez avec des technologies sans serveur et des microservices orientés cloud, Java et d'autres langages pour la JVM sont de moins en moins utilisés, car ils occupent trop d'espace mémoire et se chargent trop lentement, ce qui les rend inappropriés pour utiliser avec des conteneurs de courte durée. Heureusement, cette situation commence actuellement à changer grâce à Quarkus.

Présentation


Plus je fais de DevOps, de conteneurs et de technologies sans serveur, plus je constate que j'écris mon code conteneurisé dans des conteneurs légers ou FaaS en Python ou JavaScript. Java est tout simplement trop lourd à démarrer pour être utilisé dans un cadre sans serveur. Concernant les microservices, JavaScript ou Python offrent un chargement plus rapide et des conteneurs plus compacts, ce qui rend Java plus efficace.



Python et JavaScript sont les meilleurs langages pour créer des microservices basés sur le cloud

Java a plus de 20 ans , et au moment de sa création, le monde était complètement différent de ce qu'il est aujourd'hui. Avec l'avènement de la JVM, d'énormes problèmes ont été résolus - nous avons pu écrire du code une fois et l'exécuter sur de nombreuses plates-formes et systèmes d'exploitation. Les conteneurs vous permettent de regrouper les applications, les bibliothèques et les ressources du système d'exploitation dans des conteneurs séparés, et chacun de ces conteneurs peut fonctionner n'importe où. La portabilité offerte par la JVM est désormais moins pertinente . À une certaine époque, nous étions prêts à engager des coûts supplémentaires pour assurer la portabilité, mais maintenant, ces temps sont passés. Vous avez maintenant besoin d'un travail rapide avec des délais minimaux et des applications réactives qui seront toujours disponibles . Les conteneurs et les outils d'orchestration de conteneurs tels que Kubernetes offrent ces capacités indépendamment du langage de programmation.

Les entreprises qui passent aux architectures de microservices prennent leurs services Spring écrits en Java, les lient à des archives jar lourdes, ajoutent des JDK et les exécutent dans un conteneur Linux. Cette solution fonctionne, mais vous devez gérer des conteneurs lourds de 500 Mo, qui sont mis dans un état d'accessibilité pendant 10 à 30 secondes chacun; c'est un grave problème. Après la migration, de nombreuses entreprises passent lentement à l'utilisation de Python, laissant les services côté serveur en Java et, finalement, s'arrêtent à FaaS.

Les technologies sans serveur et FaaS sont très populaires aujourd'hui car elles vous permettent de vous concentrer sur l'écriture de fonctions sans vous soucier de l'infrastructure. Quoi qu'il en soit, ils travaillent tous dans des conteneurs, mais le fournisseur de cloud gère leur cycle de vie. La meilleure partie est que, après un certain temps, le fournisseur arrête complètement le conteneur et ne reprend son travail qu'après le prochain appel, c'est-à-dire que vous ne payez que le temps de travail réel. Le premier appel de fonction peut durer un peu plus longtemps que d'habitude, c'est le fameux démarrage à froid . Le fait est que le conteneur a besoin d'un chargement primaire. L'utilisation de Python ou de JavaScript n'est pas un gros problème, mais dans le cas de Java, le chargement initial peut prendre 10 à 15 secondes, et c'est une phrase et l'une des raisons de la baisse de popularité de Java. Maintenant, nous avons besoin d'un code qui peut démarrer, terminer la tâche, puis s'arrêter . Nous ne voulons pas traiter de nombreux threads ou processus de longue durée, nous avons besoin de processus de courte durée qui peuvent se charger très rapidement .

Présentation de Quarkus


Si vous lisez des blogs techniques ou suivez l'actualité, vous pensez probablement que le paradigme sans serveur envahit le monde, et tout le monde le prend avec un enthousiasme extrême. Désormais, une startup peut écrire des fonctions et les fournir dans le cloud en tant que service - grâce à l'utilisation de JavaScript - et également les faire évoluer pour prendre en charge des millions d'utilisateurs, sans avoir à gérer l'infrastructure. Certes, il existe également un monde réel en dehors de la Silicon Valley: les institutions financières, le gouvernement, le commerce de détail et de nombreuses autres industries desservies par des millions de lignes Java, trop coûteuses à réécrire. Par conséquent, nous devons tenir pour acquis le fait que dans ces industries, il reste à utiliser des conteneurs lourds.



GraalVM et, en particulier, Substrate VM, ouvrent aujourd'hui la porte à l'avenir glorieux et à long terme du langage Java. GraalVM est une machine virtuelle universelle pour exécuter des applications écrites en JavaScript, Python, Ruby, R et des langages pour la JVM, notamment Java, Scala ou Kotlin. Le plus cool est que GraalVM vous permet de précompiler (en mode AOT) des programmes dans un fichier exécutable natif . Cela signifie que vous pouvez compiler votre code Java directement en code spécifique à la machine. Le programme résultant ne fonctionne pas sur Java HotSpot VM, mais utilise tous les composants nécessaires, en particulier la gestion de la mémoire, la planification des threads à partir d'une autre implémentation d'une machine virtuelle appelée Substrate VM. Le substrat VM est écrit en Java et son code est compilé en un exécutable natif. Le programme résultant démarre plus rapidement et, par conséquent, réduit la surcharge de la mémoire par rapport à Java VM. C'est super, mais vous pensez probablement: une compilation précoce? Cela contredit l'idée de base pour laquelle la JVM a été créée, c'est-à-dire l'utilisation de code une fois écrit partout! C'est fou !!! Cependant, pensez par vous-même: nous avons maintenant des conteneurs, et ils n'ont pas besoin d'une machine virtuelle Java. Les applications de conteneurs classiques créées à l'aide de Spring Boot ont un niveau d'abstraction supplémentaire, ce qui est absolument inutile dans le monde où se trouve Kubernetes . Vous avez une application Java en cours d'exécution sur la machine virtuelle Java à l'intérieur du conteneur, ce conteneur reste inchangé, car aujourd'hui le produit fini est un conteneur, pas une application. Maintenant, nous emballons des conteneurs, pas des fichiers WAR. Par conséquent, tous les coûts associés à l'utilisation de l'application JVM à l'intérieur du conteneur deviennent inutiles , et AOT devient une décision très logique si vous allez emballer vos applications dans des conteneurs.

Certes, la compilation AOT limite sérieusement les capacités dynamiques de Java (chargement des classes à l'exécution, réflexion, proxys, etc.). En pratique, cela signifie que 90% de l'écosystème Java ne fonctionnera pas sans changement. En conséquence, l'écosystème Java doit s'adapter . Il y a de bonnes nouvelles: la plupart de cela peut être fait pendant l'assemblage!

C'est le pouvoir de Quarkus. Il utilise GraalVM et fournit un écosystème qui prend en charge la compilation AOT au moment de la construction; ainsi, en utilisant Java, vous pouvez créer des binaires natifs. Grâce à Quarkus, GraalVM est mis à la disposition des développeurs Java .

Premiers pas avec Quarkus


Comme expliqué ci-dessus, Quarkus fournit une compilation précoce pour les applications Java, ce qui produit un écosystème de Java subatomique supersonique; Quarkus se caractérise par un chargement ultra-rapide - et Java revient au jeu dans le domaine du développement basé sur le cloud. Pendant des années, aucune nouvelle technologie ne m'a inspiré - et je ne suis pas seul dans ce domaine .

Lisez le guide du débutant - et voyez par vous-même. De nombreuses entreprises utilisent encore Java + JPA à l'intérieur du conteneur, mais dans cette configuration, le chargement peut prendre 15 secondes, et dans le cas de Quarkus, 0,005!



Statistiques Quarkus

Vous utilisez le même IDE et les mêmes outils auxquels vous êtes habitué dans le monde Spring Boot. Pour construire votre projet, utilisez Maven ou Gradle. Le projet peut être exécuté directement dans l'EDI et en plus, un redémarrage en direct à chaud est disponible pour vous avec toutes les modifications, et vous n'avez pas besoin de redémarrer l'application. Quarkus n'est pas Spring, donc si vous utilisez Spring Boot, vous devrez migrer du code spécifique à Spring. Heureusement, Quarkus offre un niveau de compatibilité pour l'implémentation des dépendances Spring , ce qui simplifie considérablement le travail. Le framework Quarkus est conforme aux normes, ce qui signifie une facilité de portage et de prise en charge de son code.

Processus de développement de Quarkus


Quarkus peut être utilisé en mode développement, ce qui n'est pas sans rappeler Spring Boot. Avec lui, vous pouvez également emballer votre projet dans un pot épais. Ceci est très pratique pour tester et déboguer votre code, car le redémarrage en direct est pris en charge; mais vous devez compiler à l'avance pour entrer en production. L'ensemble du processus est illustré dans le diagramme suivant:



  • Tout d'abord, créez l'application dans votre IDE préféré, puis vous pouvez l'exécuter en mode développeur avec: " mvnw compile quarkus:dev ", comme vous le feriez avec une application Spring Boot. Vous pouvez également l'emballer dans un pot épais.
  • Dès que vous avez terminé l'étape précédente et que le résultat vous convient - vous êtes prêt à créer le fichier binaire Java, lancez simplement: « mvnw package -Pnative ». Cela prendra un certain temps, car le code natif sera généré lors de la compilation à l'avance! Une fois cette étape terminée, vous aurez à votre disposition un fichier exécutable ultra-petit et ultra-rapide, mais il ne pourra fonctionner que sur votre plateforme / OS, c'est-à-dire qu'il ne sera pas porté! Mais c'est normal, puisque nous pouvons le mettre dans un conteneur - et ainsi assurer la portabilité. Voici comment procéder: ./mvnw package -Pnative -Dnative-image.docker-build=true 4 - et nous ./mvnw package -Pnative -Dnative-image.docker-build=true l'exécutable du conteneur Docker, c'est-à-dire que nous effectuons l'assemblage natif à l'intérieur du conteneur et créons un fichier binaire. Cette technique peut ne pas fonctionner sur votre ordinateur portable si son système d'exploitation est différent de la plate-forme cible spécifiée dans le DockerFile généré par Quarkus lors de la création du projet.
  • Ensuite, après avoir le binaire, créez simplement une image basée sur le fichier docker. docker build -f src/main/docker/Dockerfile.native -t quarkus-quickstart/quickstart .
  • Enfin, l'application peut être lancée dans Docker ou Kubernetes: docker run -i --rm -p 8080:8080 quarkus-quickstart/quickstart

Caractéristiques de Quarkus


Quarkus possède bien plus de fonctionnalités que le code Java natif.

  • Unification des capacités impératives et réactives: permet de combiner du code impératif familier avec du code non bloquant écrit dans un style réactif.
  • Le développeur est content : une configuration unifiée, Zero config, redémarrage en direct en un rien de temps, code optimisé rationalisé pour 80% des cas courants et code flexible pour les 20% restants, génération de fichiers exécutables natifs sans tracas, codage en direct.
  • Chargement incroyablement rapide, une zone de mémoire résidente incroyablement petite (oui, ce n'est pas seulement une question de taille de tas!), Qui offre une mise à l'échelle verticale presque instantanée et une utilisation de la mémoire très dense lors de l'orchestration de conteneurs sur des plates-formes comme Kubernetes. Voir plus de détails .
  • Quarkus offre un cadre complet de pile complet et convivial, avec des bibliothèques de première classe que vous connaissez et aimez incorporées dans les structures de support. Plus de détails .
  • Les bibliothèques Hibernate, JPA, REST, JWT, etc. sont prises en charge.
  • Configurations prises en charge déployées dans Kubernetes et OpenShift
  • Ouvrir le traçage avec Jaeger
  • Assistance Kotlin
  • Messagerie avec Kafka, Camel ...
  • Et bien plus, consultez la liste des extensions !

Écosystème Quarkus


En bref, vous pouvez désormais exécuter des services transactionnels JPA / JTA traditionnels dans des conteneurs légers ultrarapides - à la fois dans le cloud et sur site .

Exemple Quarkus


Dans cette section, jetons un coup d'œil simplifié au guide du débutant pour vous donner une idée de la puissance de Quarkus.



La façon la plus simple de créer un nouveau projet Quarkus consiste à ouvrir une fenêtre d'invite de commandes et à y exécuter la commande suivante:

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

Cela génère un projet Maven avec GreetingResuce fournissant le point de terminaison / bonjour. Des images Dockerfile docker pour les fichiers natifs et jvm (images traditionnelles sous forme de bocal épais) sont également générées. Le code est très propre et simple:

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

Pour exécuter l'application, utilisez: ./mvnw compile quarkus:dev
L'application est mise en package à l'aide du package ./mvnw. Le résultat est 2 fichiers jar:

  • getting-started-1.0-SNAPSHOT.jar - contient uniquement des classes et des ressources de projet. Il s'agit d'un artefact commun résultant de l'assemblage de Maven;
  • getting-started-1.0-SNAPSHOT-runner.jar est un fichier exécutable. Notez que ce n'est pas «uber-jar», il y a des dépendances ici, elles sont copiées dans le répertoire target / lib.

Vous pouvez démarrer l'application en utilisant: java -jar target / getting-started-1.0-SNAPSHOT-runner.jar

Ensuite, vous devez télécharger et installer GraalVM et définir la variable d'environnement GRAALVM_HOME .

Vous pouvez maintenant créer un exécutable natif avec: ./mvnw package -Pnative -Dnative-image.docker-build=true .

Voici comment créer une image Docker: docker build -f src/main/docker/Dockerfile.native -t quarkus-quickstart/quickstart .

Maintenant, il peut être lancé à l'aide de n'importe quel moteur d'orchestration de conteneurs, si vous utilisez minishift :

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

 kubectl expose deployment quarkus-quickstart --type=NodePort 

C'est tout! Vous avez maintenant un conteneur avec un service Java REST qui démarre en 0,004 secondes!

Conclusion


Je comprends maintenant pourquoi je suis si impressionné par le framework Quarkus pris en charge par Red Hat. Je crois vraiment que cela va changer le paysage technologique de Java et offrir aux grandes entreprises traditionnelles une réelle opportunité de migrer vers le cloud.

Kubernetes + Knative + Quarkus change les règles du jeu dans un développement orienté cloud et plaira à tout développeur Java.

Ce référentiel contient de nombreux exemples intéressants!

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


All Articles