Qu’est-ce que Quarkus ?

Le langage de programmation Java est reconnu de longue date comme une institution dans le secteur informatique. Il est apparu durant les premières années d’internet, mais le Web s’est développé à toute vitesse depuis. Outre l’architecture classique client-serveur, il existe un vaste éventail de modèles alternatifs dignes d’intérêt : les applications basées sur des conteneurs, les microservices, l’informatique sans serveur, et les applis Web réactives se sont imposés dans la vie de tous les jours. Ces types d’applications ont jusqu’à présent été difficile à configurer avec Java. Grâce à la structure Quarkus, les choses ont commencé à changer. Le manager de RedHat Ken Johnson exprime cela ainsi :

Citation

« … it’s a very small Java stack, perfect for containers, serverless and other scenarios where you’re running Java applications in the cloud. »

– Ken Johnson, source : https://www.openshift.com/blog/quarks-is-here-for-your-java

Translation : « … il s’agit d’une toute petite Java stack, qui est parfaite pour les conteneurs, le sans serveur et d’autres scénarios où des applications Java sont exécutées sur le Cloud. » (traduit par IONOS)

Dans cet article, nous allons vous présentez Quarkus et vous montrer dans quelle mesure cette structure révolutionne la création d’applications Java.

Qu’est-ce qui rend Quarkus spécial ?

Quarkus est une structure développée par RedHat pour créer des applications Java. Quarkus a été développé dans le but d’exécuter des programmes Java dans des conteneurs. Elle se concentre en particulier sur le fait de soutenir le logiciel d’orchestration Kubernetes. Un autre point focal du développement de Quarkus concerne l’utilisation des bibliothèques et des standards établis de Java.

« HotSpot », du projet OpenJDK, est utilisé comme une Machine Javal Virtuelle (JVM) en tant que couche d’exécution du code Java. En outre, le développement « GraalVM », qui développe à partir de HotSpot, peut également être utilisé. Ce dernier permet au code Java d’être compilé en code informatique exécutable directement. Pour comprendre quel avantage immédiat apporte l’utilisation de Quarkus, examinons d’abord de quelle manière les applications Java sont exécutées avec et sans Quarkus.

Comment les applications Java sont-elles traditionnellement exécutées ?

L’idée fondamental qui a rendu Java révolutionnaire lors de son apparition était aussi simple que fascinante : Java rendait possible le fait d’écrire un programme sans être dépendant d’un support matériel ou d’un système d’exploitation spécifique. L’indépendance d’une telle plateforme est souvent résumée en cette simple phrase : « write once, run anywhere » (« écrire une fois, exécuter n’importe où »). La portabilité inhérente à ce programme lui permet d’être déplacé d’une plateforme à l’autre. Un vrai tour de magie ! Mais alors, comment ça marche ?

De même que pour les autres langages de programmation, un programme Java commence avec un code source qui peut être lu par un être humain. Dans l’optique d’exécuter les instructions du texte source sur un ordinateur, des instructions ciblées sont générées au format du processeur spécifique. Avec Java, une autre étape intermédiaire entre en jeu : le texte source est d’abord traduit dans un format intermédiaire, que l’on appelle le bytecode (« code en byte »), comme c’est le cas avec le langage Python. Le bytecode est ensuite exécuté dans la « Machine Virtuelle Java » (JVM). Si l’on souhaite exécuter un programme Java sur un appareil, un JVM doit y être installé.

Le bytecode est traditionnellement interprété pour être exécuté dans le JVM. Les instructions en bytecode sont traduites morceau par morceau en des instructions en code machine et exécutées. Le processus de « compilation juste à temps » (JIT) est plus efficace. Avec ce processus, le bytecode est également converti en code machine, mais une optimisation complémentaire entre également en jeu. En gros, exécuter un programme Java implique de suivre les étapes suivantes :

  1. Compiler le code source Java en bytecode avec la commande de compilation Java 'javac' :
javac java_program.java
  1. Exécuter le bytecode Java avec la commande d’exécution 'java' – le code machine est alors généré :
java java_program
Note

Nous parlons ici d’une « machine virtuelle ». Bien que le terme soit le même, en l’occurrence, il ne renvoie à aucun type de technologie dédié à rendre un système d’exploitation virtuel. Au lieu de cela, le code intermédiaire est traduit en code machine.

Si pratique que soit le modèle « write once, run anywhere » de Java, cette approche présente quelques faiblesses : avoir recours au JVM implique des limites non négligeables. D’un côté, démarrer le JVM prend un certain temps, lequel vient s’ajouter au temps d’exécution de l’application en elle-même. D’un autre côté, outre la consommation de mémoire plus élevée, une perte en termes de performances est notable. Tout ceci joue un rôle mineur s’agissant des applications qui sont exécutées sur une longue période. En revanche, cette approche ne convient que peu aux applications à courte durée de vie et basées sur des conteneurs. Dans un monde idéal, celles-ci devraient démarrer le plus vite possible. Il est inacceptable d’attendre quelques secondes pour les voir se lancer.

Comment les applications Java sont-elles exécutées avec Quarkus ?

À la différence de l’exécution native des applications Java, Quarkus offre plusieurs avantages. Etablissons une différence entre les deux modes supportés par Quarkus :

  1. Optimisation du bytecode et exécution dans le JVM
  2. Exécution en tant que code natif après la compilation

Le code Java écrit avec Quarkus peut être exécuté normalement dans le JVM. Quoi qu’il en soit, il existe des avantages considérables en termes de consommation de mémoire et de temps de démarrage d’une application en cours d’exécution. Pour parvenir à cela, Quarkus a recours à quelques astuces. Plus précisément, un certain nombre d’étapes chronophages sont déplacées du processus d’exécution à celui de développement. Ceci comprend les étapes qui, dans les autres cas, ont lieu à chaque fois qu’une application Java est exécutée :

  • Charger et analyser les configurations
  • Scanner le chemin de classe Java et résoudre les annotations
  • Créer des modèles d’entités pour les bases de données ou équivalents lorsque cela s’applique

Avec Quarkus, ces étapes sont menées à bien une seule fois et les résultats sont mis en cache pour une récupération rapide. Une optimisation complémentaire des performances a lieu via le fait, pour Quarkus, de réduire la quantité d’information dynamique disponible à l’exécution. Ceci est remplacé par des constructions statiques correspondantes. C’est particulièrement utile quant à l’utilisation qui a lieu dans les conteneurs. Une application conteneurisée n’est de toute façon généralement pas modifiée et est toujours exécutée dans le même environnement.

Le second mode supporté par Quarkus pour exécuter des applications Java est encore plus intéressant. Avec la compilation anticipée (AOT), un code machine directement exécutable est généré depuis la source Java à la place du bytecode, ce qui signifie qu’il n’y a plus besoin d’un JVM sur le matériel cible. Le programme est uniquement exécutable sur des architectures de processeur spécifiques et doit être compilé à nouveau sur d’autres plateformes. Quoi qu’il en soit, cette restriction n’est en général pas pertinente pour un usage dans des conteneurs. Les économies en termes de consommation de mémoire et de temps de démarrage d’applications réalisées grâce à la compilation AOT sont tout simplement époustouflantes. Comparez les niveaux références de performance exposés ci-dessous depuis la page d’accueil officielle de Quarkus :

Application Scénario Mémoire utilisée Durée avant la première réponse
Quarkus + AOT REST 12 MB 0.02 s
Quarkus + AOT REST + CRUD 28 MB 0.04 s
Quarkus + JIT REST 73 MB 0.94 s
Quarkus + JIT REST + CRUD 145 MB 2.03 s
Cloud Native Stack REST 136 MB 4.3 s
Cloud Native Stack REST + CRUD 209 MB 9.5 s
Note

En ce qui concerne la terminologie : REST signifie que seul un serveur Web est en cours d’exécution dans le conteneur. Dans le scénario REST + CRUD, une base de données est exécutée en même temps que le serveur Web. Pour une stack Cloud native, le conteneur contient un JVM, en supplément de l’application Java.

Dans quel but utilise-t-on Quarkus ?

Quarkus est bien plus qu’une simple structure d’application : ce logiciel a été conçu pour redéfinir ce que cela signifie de développer des applications avec Java. À titre de rappel : traditionnellement, il était plus important pour une application Java d’être exécutée de manière stable sur une longue période. Le temps que mettait une application à démarrer était perçu comme secondaire.

Prenez les applications basées sur des conteneurs : de nouveaux conteneurs peuvent être lancés automatiquement par un logiciel d’orchestration. L’application dans le conteneur doit alors être prête à être immédiatement utilisée. En outre, plusieurs conteneurs redondants sont souvent lancés pour un même service. La réduction en termes de consommation de ressources réalisée avec Quarkus est multipliée en conséquence.

Le manager de RedHat Alex Handy résume les choses ainsi :

Citation

« When you think of serverless computing, microservices and the […] cloud, there’s one language you’re probably not [thinking of]: Java. And that’s a real shame. […] Java was and is the workhorse language of business. It remains the third most popular language in the world […] It’s been the language of choice for corporations that need to keep a single application up and running for years at a time. »

– Alex Handy, source : https://thenewstack.io/quarkus-gives-spring-boot-users-a-path-to-serverless-and-live-coding/

Traduction : « Lorsque vous pensez à l’informatique sans serveur, aux microservices et au […] Cloud, il y a un langage auquel vous ne [pensez] probablement pas : Java, et c’est vraiment dommage […] Java était et est encore le cheval de bataille des langages dans le monde des affaires. Il reste le troisième langage le plus populaire au monde […] Il n’a cessé d’être le choix n°1 des entreprises qui ont besoin d’avoir une application à la fois qui reste fonctionnelle et performante pendant des années. » (traduit par IONOS)

Les avantages de Quarkus sont évidents. Quoi qu’il en soit, la structure connaît aussi quelques limites. En tant que tel, Quarkus n’a pas été conçu, au départ, pour migrer des applications Java existantes. Au contraire, il vaut mieux utiliser Quarkus en tant que point de départ pour un nouveau développement. Nous allons jeter un œil à quelques zones d’application spécifiques ci-dessous. Dans tous les exemples cités, Maven ou Gradle est utilisé en tant qu’outil de développement. La zone d’application est déterminée en configurant la commande « mvn » ou « gradle ». L’outil de développement génère ensuite automatiquement les configurations et artefacts nécessaires.

Exécuter des applications de microservice dans Kubernetes avec Java et Quarkus

Kubernetes constitue un logiciel d’orchestration pour les applications conteneur. Il est assez courant d’avoir recours à Kubernetes avec des conteneurs Docker. Les services individuels d’une application sont sauvegardés en tant qu’images Docker et gérés par Kubernetes. L’orchestrateur prend en charge la gestion des conteneurs générés depuis les images : Kubernetes démarre, contrôle et supervise les services. Souvent, plusieurs copies d’un même service sont lancées pour partager la charge et augmenter la tolérance aux pannes. Si l’un des services s’interrompt, le conteneur est détruit et un autre conteneur est créé depuis la même image. Java Quarkus comprend les configurations qui sont nécessaires pour un usage dans Kubernetes.

Mettre en œuvre des APIs REST et des applications sans serveurs avec Java et Quarkus

REST est un style d’architecture établi de longue date pour les applications Web. Les APIs en particulier sont principalement mises en place en suivant cette approche. Une API REST est basée sur une architecture serveur-client. La communication prend place via le protocole http à l’aide des « verbes » GET, POST, PUT, DELETE. Ceux-ci correspondent aux fameux « verbes » CRUD (« create, read, update, delete » (« créer, lire, actualiser, supprimer ») issus de l’environnement des bases de données. Un échange de données entre une API et un utilisateur prend en général place via JSON.

L’informatique sans serveur constitue une architecture alternative pour les applications basées sur le Cloud. Dans ce modèle, également connu sous le nom de « Function as a Service » (« Fonction en tant que service ») (FaaS), une seule fonction est exécutée brièvement dans un conteneur. La fonction est appelée, réalise un calcul, et est à nouveau éteinte. En dépit de son nom, les fonctions sans serveurs continuent à être exécutées sur des serveurs. Les programmeurs n’ont plus à s’inquiéter à leur sujet. Avec AWS Lambda, les Fonctions Google Cloud et les Fonctions Microsoft Azure, les environnements sans serveurs sont disponibles sur toutes les principales plateformes de Cloud. Le code Java peut être utilisé sur ces plateformes par le biais de Quarkus.

Conseil

Créez votre propre API-REST sur un serveur dédié de IONOS.

Développer des applis Web réactives à l’aide de Java et Quarkus

À la différence de la programmation impérative, la programmation réactive représente un paradigme de programmation moderne. Les actions qui devraient avoir lieu lorsque certains événements se produisent sont décrites par un programmeur. Les représentants les plus célèbres de ce style de programmation sont les structures « React » et « Vue », écrites en JavaScript. Chacune de celles-ci se focalise sur la création d’interfaces utilisateur basées sur le Web. Avec Quarkus, les applications peuvent être mises en œuvre dans un style impératif et réactif. Il est même possible de combiner les deux paradigmes.

Où Quarkus est-il utilisé ?

Quarkus a été conçu dans l’optique d’optimiser les applications Java pour qu’elles soient utilisées dans des conteneurs et des environnements Cloud. La possibilité de compiler un programme Java directement dans du code machine, néanmoins, ouvre des possibilités d’applications autrement plus intéressantes. Jetons un œil aux zones d’application actuelles les plus intéressantes de Quarkus.

Commençons par nous rappeler comment est exécuté un programme Java développé avec Quarkus. Au fil du processus de développement, le code source Java est compilé en bytecode, lequel est ensuite traduit en code machine lorsqu’il est exécuté. Le bytecode peut être exécuté avec Quarkus, qui est ensuite exécuté dans un environnement d’exécution Java, tel que le HotSpot VM, via interprétation ou compilation à la volée (JIT). Selon la configuration, diverses optimisations pertinentes sur le plan des performances entrent en jeu.

D’un autre côté, GraalVM, basé sur HotSpot, peut être utilisé pour générer une image native à l’aide d’une compilation anticipée (AOT). L’image native est un fichier binaire qui contient toutes les bibliothèques et dépendances nécessaires pour exécuter l’application. Dans la mesure où aucun JVM n’est nécessaire pour l’exécution, les gains de performance les plus importants sont gagnés via une compilation AOT.

Les applications Java dans les environnements de conteneur

Kubernetes entre en général en ligne de compte lorsque l’on utilise une appli Java dans des conteneurs. On peut également avoir recours à une appli Java packagée comme une image Docker sur un cluster OpenShift. L’utilisation de Quarkus avec Kubernetes peut également être testée par vos soins, par exemple, en passant par l’installation de minikube sur votre système local.

Les fonctions Java dans les environnements sans serveurs

Utilisez Quarkus pour mettre facilement en place une fonction écrite en Java dans des environnements sans serveur d’Amazon, Google et Microsoft.

Les programmes Java dans les systèmes intégrés

Compte tenu de la capacité à créer une image native depuis une application Java, le code Java peut également être utilisé dans les systèmes intégrés. La compilation AOT se révèle utile ici, étant donné qu’elle permet une faible consommation de mémoire et des durées de démarrage rapides pour une application spécifique.

Conseil

Utilisez Managed Kubernetes de IONOS pour vos applis basées sur les conteneurs.

Quarkus comparé à d’autres structures

Quarkus convient à un vaste éventail de différents scénarios d’applications. D’autres structures sont plus spécifiques à certains égards. Jetons à un œil à quelques alternatives similaires.

  • React : cette structure JavaScript s’est érigée en standard dans le domaine éponyme de la programmation réactive.
  • Open Liberty : cette structure d’IBM permet également le développement d’applications de microservice avec Java. À l’instar de Quarkus, Open Liberty comprend une fonctionnalité de rechargement à chaud.
  • Micronaut : avec la structure Micronaut, les microservices et les applications sans serveurs peuvent être programmées dans Java. De même qu’avec Quarkus, GraalVM est utilisé ici.
  • Spring/Spring Boot: Spring est probablement la structure Java la plus populaire pour les applications Web. Spring est basé sur GraalVM et, outre la création de microservices, il supporte la programmation réactive et le rechargement à chaud. Si on compare leurs performances, Quarkus l’emporte sur Spring. Un projet Spring en cours peut être migré vers Quarkus de manière relativement facile.

Quels sont les avantages et les inconvénients de Quarkus ?

Le principal avantage de développer des applications avec Quarkus est le gain en termes de performances. Ceci revêt une importance particulière lorsque l’on a recours à des applications Java dans des environnements de conteneurs. Les bénéfices en termes de performances comprennent :

  • Une durée de démarrage d’application rapide
  • Une faible consommation de mémoire par l’application en cours d’exécution
  • Un échelonnage des services quasi-immédiat
  • Un faible espace nécessaire pour les images natives

Outre ses avantages sur le plan des performances, Quarkus brille plus que tout par son ergonomie. Les développeurs habitués à Java EE et Spring peuvent aisément apprendre à utiliser la structure. Ils bénéficient également du fait que Quarkus est basé sur une structure solide. Les technologies standard suivantes sont utilisées, en plus des autres :

  • Eclipse MicroProfile
  • Spring Dependency Injection
  • Hibernate ORM

Quarkus offre également un environnement de code en ligne, dans lequel les développeurs peuvent rapidement créer des prototypes. La fonctionnalité de rechargement à chaud contribue à un développement tout en douceur : après avoir activé le mode dev, les changements apportés au code source et à la configuration sont compilés en arrière-plan. Le développeur doit seulement recharger la fenêtre du navigateur pour comprendre ces changements.

Enfin, nous pouvons conclure avec les inconvénients d’utiliser Quarkus. Ces derniers concernent principalement des optimisations qui entrent en jeu lors de la compilation.

  • En particulier, réduire les informations dynamiques générées durant l’exécution peut conduire à des problèmes dans le cadre de certains scénarios.
  • Les possibilités d’introspection limitées à l’extrême peuvent rendre difficile le fait de débugger une application.
  • Le processus hautement optimisé de développement des images natives prend beaucoup de temps.

Quarkus n’a pas été conçu pour le premier projet Java venu. À certains égards, utiliser cette structure nécessite que des processus soient convertis.