Les performances en Java Spring boot : comment les optimiser ?

Comprendre les performances en Java Springboot et les optimiser.
Philippe.jpg
Philippe AUBERTIN, Javaman aigriMis à jour le 23 Août 2021
performances spring boot

Pourquoi parler des performances de Spring Boot ?

La question des performances d’une application web est primordiale au ressenti utilisateur.

Spring Boot est utilisé dans la majorité du temps pour réaliser des APIs qui servent à des applications web (clients web) développées en Javascript (Angular, React, VueJs). Grâce à l’AJAXLe petit nom de Asynchronous JavaScript + XML, une nouvelle approche pour rendre dynamique un site web., l’affichage est plus fluide qu’avec un rechargement de page entière, néanmoins, attendre quelques centaines de millisecondes pour voir un élément se charger peut rapidement être désagréable, aussi bien pour l’utilisateur, que pour le serveur !

Voici quelques raisons pour lesquelles vous devriez vous soucier des performances de vos APIUne API est un programme permettant à deux applications distinctes de communiquer entre elles et d’échanger des données. sur Spring BootFramework Java se basant sur Spring. :

  1. Des requêtes plus rapides, c’est une satisfaction utilisateur plus grande
  2. Des traitements plus rapides, c’est moins de charges serveur et donc moins de serveurs (Cluster, Docker, Kubernetes, VM, machine, quelque soit votre solution d’hébergement...). Et donc un coût bien moindre !
  3. Qui dit traitement plus rapide, dit in fine moins de calcul et une consommation énergétique moindre
  4. Enfin, plus le traitement est optimisé, moins il a de chances de planter ! Et ça pour deux raisons au moins : un traitement optimisé est un traitement pensé, et puis, parce que plus un traitement dure, plus il y a des chances que quelque chose se passe mal ! (Timeout, mauvaise transaction, contexte changeant...)

Par où commencer pour améliorer les performances Springboot ?

On ne pilote bien que ce qu’on mesure bien ! Cet adage est encore plus vrai pour les performances.

Faire un constat des performances de son application sans concession !

On commence par utiliser des outils pour mesurer les temps de réponse de son application, et on le fait de manière la plus exhaustive qui soit. Chaque composant, brique, service de son application doit renvoyer de l’information à un système central pour le superviser. On ne peut que vous recommander d’utiliser un service monitoring à la hauteur. Commencez par étudier les solutions d’observabilité ! (et pour mettre fin à quelques débats, on peut tout mesurer, même les vieilles technologies... Pas d’excuses ;) )

La méthode des petits pas pour les performances Spring Boot

Une fois le constat partagé, choisissez votre cheval de bataille, LA transaction métier que vous souhaitez améliorer ! Placez-vous côté métier et posez-vous la question suivante : quel est le processus métier qui a le plus de valeur dans mon application ?

Continuez en réunissant vos équipes DevOps et Dev autour de la problématique. Posez-leur le constat et le cadre de manière simple : "Pour la réalisation de ce processus, il faut 15 secondes du début à la fin. Nous aimerions améliorer ce processus qui est cœur dans l’application, qu’est-ce que chacun peut faire dans sa partie ?" Laissez-les ensuite réfléchir et descendre le processus en appels aux services et à l’API. Une fois les services améliorables identifiés, c’est seulement à ce moment-là qu’on peut descendre d’un cran et analyser le code et le Spring Boot pour l’amélioration des performances. Avant cette étape d’identification, vous perdez votre temps à essayer d’améliorer à l’aveugle !

Les clés des performances JAVA en Spring Boot

Rien n’est magique en informatique et encore moins en JAVA et en Spring Boot, le temps et la mémoire ne se volatilisent pas sans raison...

Il faut revenir à la base : 1 seconde de temps de traitement pour un serveur, c’est plusieurs milliards d’opérations ! On peut en faire des choses avec ! Et il est bon de rappeler à nos chers développeurs - dont je fais partie - qu’avec quelques ordres de grandeur de moins, on arrivait à sauvegarder peu ou prou les mêmes données dans les années 90 ! Alors non, ce n’est pas normal que pour sauvegarder votre fiche client, il faille plusieurs secondes et plusieurs Go de RAM !

"Ouais, mais JAVA, il consomme beaucoup de RAM" <== cette réplique m’énerve au plus haut point. Oui JAVA n’est pas le plus économe en mémoire, mais ce sont des débats d’experts et pour les développeurs de manière générale, les impacts sont minimes de nos jours entre les langages. Pour preuve, voici un Spring Boot vide et son empreinte mémoire. 

spring-boot-vide-empreinte-memoire.png
)

Pour lancer un serveur capable de répondre à des requêtes WEB, Spring Boot et JAVA prennent 11 Mo ! Donc le reste de la mémoire mes amis, c’est pour nous les développeurs... Arrêtons donc un peu de se cacher derrière la technologie pour masquer notre paresse pour optimiser notre code :)

Alors, pourquoi c’est lent docteur ?

Il existe de nombreux facteurs, et non, il n’existe pas un paramètre à mettre dans Spring Boot pour que d’un coup, ça aille vite !

Cependant, voici ici certaines mauvaises habitudes qu’on peut voir souvent dans les projets et qui expliquent les problèmes de performances Springboot.

Mauvaise utilisation d’Hibernate

Utilisateur des EAGER, pas d’utilisation des requêtes natives, pas de cache, pas de prepared statement, modèles de données confus.. Autant de mauvaises pratiques dans l’utilisation d’Hibernate ! Mais la bonne nouvelle, c’est que c’est très facile à corriger.

Avec un bon outil, vous pouvez facilement récupérer les requêtes ! Les outils de monitoring peuvent le faire tout seul mais sinon, vous pouvez simplement former vos développeurs à le faire.

Algorithmes complexes qui font souvent appel à la même méthode

On peut citer comme exemple d’algorithmes complexes qui font souvent appel à la même méthode : la récupération des utilisateurs. Dans 90% des applications, l’utilisateur est recherché dans la base de données plusieurs fois pour chercher ses droits, pour son nom, mettre à jour les logs de l’utilisateur... De la même manière avec un peu de rework, il est facile de régler ces problèmes.

Pas d’utilisation de cache

Avec Spring Boot, vous pouvez mettre des caches à un peu près tout et n’importe quoi ! Dans votre contrôleur, dans votre service, dans votre repository, ou sur n’importe quelle méthode !

Les classiques de JAVA

Mauvaise gestion de strings, fuite de mémoire, mauvaise utilisation des streams, sérialisation... tous les classiques JAVA !

Oui oui, on peut aussi jouer sur les paramètres de la JVM et sur les paramètres Spring Boot bien sûr, mais la majorité du temps, ce sont des petits gains. Alors que réécrire un bout de code, ça peut vous optimiser de x1000 !

Comment on fait pour améliorer les performances Java SpringBoot ?

Je vous conseille d’utiliser l’approche suivante.

On essaye d’optimiser une requête (service) à la fois, on branche un profiler et on mesure tout, vraiment tout sur ce traitement... Chaque milliseconde, chaque entrée de méthode, de fonction, d’appel à la BDD, réseau, etc... Et on regarde où on perd le plus de temps. On travaille avec les temps relatifs et pas les temps absolus évidemment, car vous êtes sur un environnement de développement et le profiler vous ralentit un peu ! Mais le relatif est toujours bon, donc si vous passez 60 % du temps dans une méthode, c’est là votre meilleure piste d’amélioration ! Alors on regarde le code de la méthode et on cherche à l’améliorer. Oui on peut toujours améliorer une méthode ! Puis on re-teste, on regarde le profil de réponse, et on s’aperçoit que la méthode améliorée ne pèse plus que 20% du temps de traitement et que c’est une autre méthode qui prend 40%... et bien on recommence, jusqu’à ce qu’on n’arrive plus à rien faire. En appliquant cette méthode hyper simple, on améliore systématiquement les performances !

Arrêtons-nous sur le bon sens. Je n’aime pas spécialement le bon sens d’habitude, mais c’est intéressant de l’utiliser dans les performances, car il faut sans cesse se poser la question de l’intérêt de tel bout de code, et de l’intérêt de récupérer autant de données dans son traitement. Et si un développeur vous répond que c’est normal de mettre 3 secondes pour récupérer une fiche client... Challengez-le en demandant à un autre développeur ! Vous finirez par trouver quelqu’un que ça choquera :)

Pour le profiler, je vous recommande l’utilisation de jProfiler qui est à mon sens le meilleur profiler JAVA (payant).

Conclusion

On peut toujours améliorer les performances de son application JAVA Spring Boot, il suffit de s’y pencher ! Si vous avez besoin d’être accompagné sur le sujet, n’hésitez pas à nous contacter.