Dans cet article, nous allons comparer certaines mesures essentielles des applications Web utilisant deux piles Java différentes : Spring Boot et Eclipse Micro Profile. Plus précisément, nous allons implémenter la même application Web dans Spring Boot 3.0.2 et Eclipse Micro Profile 4.2. Ces versions sont les plus récentes au moment de la rédaction de cet article. Puisqu’il existe plusieurs implémentations d’Eclipse Micro Profile, nous allons utiliser l’une des plus connues : Quarkus. Au moment d’écrire ces lignes, la version la plus récente de Quarkus est la 2.16.2.
Cette mention est importante concernant Eclipse Micro Profile car, contrairement à Spring Boot, qui ne repose sur aucune spécification et, par conséquent, la question de l’implémentation ne se pose pas, Eclipse Micro Profile a été largement adopté par de nombreux éditeurs qui fournissent différentes implémentations, parmi lesquelles Quarkus, Wildfly, Open Liberty et Payara sont parmi les plus évangéliques.
Dans cet article, nous allons implémenter la même application Web en utilisant deux technologies différentes, Spring Boot et Quarkus, telles que que de comparer leurs deux métriques essentielles respectives : RSS (Taille de l’ensemble résident) et ITF (Délai de première demande).
Le cas d’utilisation
Le cas d’usage que nous avons choisi pour l’application web à mettre en place est assez classique : celui d’un micro-service chargé de gérer les communiqués de presse. Un communiqué de presse est une déclaration officielle délivrée aux membres des médias d’information dans le but de fournir informations, créer une déclaration officielle ou faire une annonce publique. Dans notre cas simplifié, un communiqué de presse consiste en un ensemble de données comme un nom unique décrivant son sujet, un auteur et un éditeur.
Le micro-service utilisé pour gérer les communiqués de presse est très simple. Comme pour tout micro-service, il expose une API REST permettant les communiqués de presse CRUD. Toutes les couches requises, comme le domaine, le modèle, les entités, les DTO, le mappage, la persistance et le service, sont également présentes. Notre propos ici n’est pas de discuter de la structure des micro-services et mode de fonctionnement mais de proposer un cas d’utilisation commun à implémenter dans les deux technologies similaires, Spring Boot et Quarkus, pour pouvoir comparer leurs performances respectives à travers les métriques mentionnées.
Taille de l’ensemble résident (RSS)
RSS est la quantité de RAM occupée par un processus et se compose de la somme des espaces JVM suivants :
- Espace de tas
- Métadonnées de classe
- Piles de fils
- Code compilé
- Collecte des ordures
RSS est une métrique très précise, et la comparaison des applications en fonction de celle-ci est un moyen très fiable de mesurer leurs performances et empreintes associées.
Délai de première demande (TFR)
Il existe une préoccupation commune concernant la mesure et la comparaison des temps de démarrage des applications. Cependant, l’enregistrer, comme c’est généralement le cas, ne suffit pas. L’heure que vous voyez dans votre fichier journal comme étant l’heure de démarrage de l’application n’est pas exacte car elle représente l’heure de démarrage de votre application ou de votre serveur Web, mais pas celle requise pour que votre application commence à recevoir des requêtes.
Les serveurs d’applications et Web, ou les conteneurs de servlets, peuvent démarrer en quelques millisecondes, mais cela ne signifie pas que votre application peut traiter les requêtes. Ces plates-formes retardent souvent le travail tout au long du processus et peuvent donner une fausse indication d’initialisation paresseuse sur le TFR. Ainsi, pour déterminer précisément le TFR, dans ce rapport, nous utilisons le script time.js de Clément Escofier, trouvé ici dans le dépôt GitHub, qui illustre l’excellent livre Reactive Systems in Java de Clément Escoffier et Ken Finnigan.
Implémentation de Spring Boot
Pour comparer les métriques présentées ci-dessus pour les deux implémentations, vous devez cloner et exécuter les deux projets. Voici les étapes requis pour faire l’expérience de l’implémentation de Spring Boot :
$ git clone https://github.com/nicolasduminil/Comparing-Resident-Size-
Set-Between-Spring-Boot-and-Quarkus.git metrics
$ cd metrics
$ git checkout spring-boot
$ mvn package
$ java -jar target/metrics.jar
Ici vous commencez par cloner le dépôt GIT, et une fois cette opération terminée, vous allez dans le répertoire racine du projet et faites un build Maven. Ensuite, vous démarrez l’application Spring Boot en exécutant le über JAR créé par le spring-boot-maven-plugin
. Vous pouvez maintenant tester l’application via son interface utilisateur Swagger exposée en allant ici. Veuillez prendre un moment pour utiliser la fonctionnalité qui l’essaie proposée par Swagger UI. L’ordre des opérations est le suivant :
- Premièrement la
POST
point final est de créer un communiqué de presse. Veuillez utiliser l’éditeur pour modifier la charge utile JSON proposée par défaut. En faisant cela, vous devriez laisser le champpressReleaseId
ayant une valeur de « 0 » car il s’agit de la clé primaire qui sera générée par l’opération d’insertion. Dessous, vous pouvez voir un exemple de personnalisation de cette charge utile :{ "pressReleaseId": 0, "name": "AWS Lambda", "author": "Nicolas DUMINIL", "publisher": "ENI" }
- Ensuite, un
GET /all
est suivi d’unGET /id
pour vérifier que l’opération précédente a bien créé un communiqué de presse. - UN
PUT
pour modifier le communiqué de presse actuel. - UN
DELETE /id
nettoyer.
Note: étant donné que l’ID est automatiquement généré par une séquence, comme expliqué, le premier enregistrement aura la valeur « 1 ». Vous pouvez utiliser ceci valeur dans GET /id
et DELETE /id
demandes. Notez que le nom du communiqué de presse doit être unique.
Maintenant, une fois que vous avez expérimenté votre micro-service, voyons son RSS associé. Procédez comme suit:
$ ps aux | grep metrics
nicolas 31598 3.5 1.8 13035944 598940 pts/1 Sl+ 19:03 0:21 java -jar target/metrics.jar
nicolas 31771 0.0 0.0 9040 660 pts/2 S+ 19:13 0:00 grep --color=auto metrics
$ ps -o pid,rss,command -p 31598
PID RSS COMMAND
31598 639380 java -jar target/metrics.ja
Ici, on récupère le PID de notre micro-service en cherchant son nom, et une fois qu’on l’a, on peut afficher son RSS associé. Remarquez que le commande ps -o
ci-dessus affichera le PID, le RSS et la commande de démarrage associée au processus, lequel PID est passé en tant que -p
argument. Et comme vous pouvez le voir, le RSS pour notre processus est de 624 Mo (639380 Ko). Si vous hésitez sur la façon de calculer cette valeur, vous pouvez utilisez la commande suivante :
$ echo 639380/1024 | bc
624
Comme pour le TFR, tout ce que vous avez à faire est d’exécuter le scénario time.js
comme suit:
node time.js "java -jar target/metrics.jar" "http://localhost:8080/"
173 ms
Pour résumer, notre micro-service Spring Boot a un RSS de 624 Mo et un TFR de 173 ms.
Implémentation de Quarkus
Nous devons effectuer ces mêmes opérations pour expérimenter notre micro-service Quarkus. Voici les opérations requises :
$ git checkout quarkus
$ mvn package quarkus:dev
Une fois notre micro-service Quarkus démarré, vous pouvez utiliser l’interface utilisateur Swager ici. Et si vous êtes trop fatigué pour utiliser l’interface graphique, vous pouvez utiliser le curl
scripts fournis dans le référentiel ( post.sh
, get.sh
etc.) comme indiqué ci-dessous:
java -jar target/quarkus-ap/quarkus-run.jar &
./post.sh
./get.sh
./get-1.sh 1
./update.sh
...
Voyons maintenant comment nous procédons concernant nos RSS et TFR :
$ ps aux | grep quarkus-run
nicolas 24776 20.2 0.6 13808088 205004 pts/3 Sl+ 16:27 0:04 java -jar target/quarkus-app/quarkus-run.jar
nicolas 24840 0.0 0.0 9040 728 pts/5 S+ 16:28 0:00 grep --color=auto quarkus-run
$ ps -o pid,rss,command -p 24776
PID RSS COMMAND
24776 175480 java -jar target/quarkus-app/quarkus-run.jar
$ echo 175480/1024 | bc
168
$ node time.js "java -jar target/quarkus-app/quarkus-run.jar" "http://localhost:8081/q/swagger-ui"
121 ms
Comme vous pouvez le voir, notre micro-service Quarkus utilise un RSS de 168 Mo, soit près de 500 Mo de moins que les 624 Mo avec Spring Boot. De plus, le TFR est légèrement inférieur (121 ms contre 173 ms).
Conclusion
Notre exercice a comparé les métriques RSS et TFR pour les deux micro-services exécutés avec la JVM HotSpot (Oracle JDK 17). Spring Boot et Quarkus prennent en charge la compilation en exécutables natifs via GraalVM. Il aurait été intéressant de comparer ces mêmes métriques de la réplique native des deux micro-services, et si nous ne l’avons pas fait ici, c’est que Spring Boot s’appuie fortement sur l’introspection Java et, par conséquent, il est nettement plus difficile à générer Micro-services natifs Spring Boot que ceux de Quarkus. Mais restez à l’écoute; ça viendra bientôt.
Le code source peut être trouvé ici. Le dépôt GIT a une branche master et deux branches spécifiques, étiquetées spring-boot
et, respectivement, quarkus
.
Apprécier!