Tir de charges : Quand les problèmes ne viennent pas du serveur d’applications

Pour les « grands » tirs de charges dont l’objectif est de tester une nouvelle application J2EE (ou JEE) avant sa mise en production, et afin d’éviter les crashs le jour du lancement, on mobilise en général une équipe des différents « corps de métier » informatiques.

On aura ainsi :

  • les « tireurs » ceux qui vont faire le tir de charges avec un outil dédié,
  • les fonctionnels qui assistent les tireurs pour la scénarisation du tir,
  • les préparateurs de données qui sont chargés de fournir des données aux injecteurs pour le tir,
  • les gens du réseau pour la surveillance du trafic et de la bande passante,
  • les DBA pour la surveillance de l’activité de la base de données,
  • les superviseurs des serveurs d’applications pour monitorer l’activité de l’application,
  • l’équipe de développement de l’application qui croisent les doigts,
  • et bien sur les chefs du fonctionnel et les chefs de la technique

Tout cela fait beaucoup de monde, on ajoutera en général un responsable général, chargé entre autre de synchroniser toutes les actions, et donner le GO du lancement.

Une fois que le tir lancé et terminé, l’expérience montre que c’est en général du coté du serveur d’applications J2EE que les problèmes sont visibles. Où s’ils ne sont pas visibles, on pense à lui en premier car c’est lui qui supporte l’application. Alors quand c’est vous le responsable de la supervision du cluster de serveurs d’applications, tout ce beau monde se retourne vers vous pour avoir l’explication, le comment du pourquoi, afin de comprendre la raison du non succès du tir de charge…

Pourtant vous avez fait une configuration des serveurs d’applications clustérisés aux petits oignons :

  • configuration de la taille minimum et maximum idéale pour ce type d’application
  • modification des paramètres de JVM pour avoir notamment un fonctionnement du Garbage Collector en (quasi) parallèle (Concurrent Mark Sweep)
  • réglage des unités d’exécution min et max, temps d’inactivité
  • réglage du pool de connexions à la base de données, avec activation du cache des requêtes SQL préparées
  • réglage du gestionnaire de sessions
  • activation du monitoring,
  • et d’autres petits réglages de derrière les fagots : taille des files d’attente TCP, nombre des requêtes keep-alive, etc

Alors avec ce tunning de folie, difficile de comprendre pourquoi le serveur d’applications souffre lors du tir de charges…

Voici quelques cas, dont le problème est visible sur le serveur d’applications, mais l’origine est ailleurs :

1/ le serveur d’applications explose en OutOfMemory… C’est en général de la faute à l’application développée ou de l’utilisation du framework de persistence (genre Hibernate). Un exemple, c’est le chargement de plusieurs fois un million d’enregistrement dans la mémoire (car plusieurs centaines d’utilisateurs simulés et non plus les quelques développeurs et testeurs de la recette). On aura ainsi par exemple, 100 fois 10 Mo dans la mémoire soit au moins 1Go, donc des OutOfMemory si la taille maximum de la mémoire JVM est à 1024 Mo.

2/ le nombre maximal des unités d’exécution est atteint. C’est en général de la faute de l’application développée ou bien de la base de données. En effet si le nombre max est atteint, mais que la CPU du serveur n’est pas utilisée, on peut en déduire que les unités d’exécution sont en attente de quelque chose… Et souvent c’est de résultat de la base de données. Soit cette dernière est surchargée, soit il manque quelques index quelque part ou tout simplement il faut régénérer les statistiques de la base de données.

3/ Tout va bien sur le serveur d’application, sur la base de données, etc, mais l’application est « lente » à la réponse. Et bien là on peut se poser la question du réseau. Il convient de s’assurer que toutes les cartes réseaux soient configurées en 100 Mbits/s Full Duplex (ou en gigabit), que les switchs d’interconnexion également (port par port), et les routeurs si il y a lieu. Le mieux est de faire un test FTP (via un client classique vers le serveur, ou via JMeter). En effet, on verra que si l’une des interfaces est en 10 Mbits/s half duplex, par exemple celle du répartiteur de charges, et l’ensemble des serveurs derrière ne seront pas surchargés, mais l’application sera désespérément lente (goulot d’étranglement sur le lien réseau). (pour l’histoire, une interface réseau peut basculer en 10 Mbits/s HD tout simplement car l’auto négociation de vitesse avec le switch a échoué, et ainsi la carte prend la valeur la plus basse…

4/ Les pages de l’application affichent des erreurs 500… c’est en général un problème applicatif engendré par un problème externe. Par exemple l’atteinte du nombre maximum autorisé de fichiers ouverts pour un processus, ou bien la base de données n’accepte plus de nouvelles connexions…

Par ailleurs, on peut aussi avoir un cumul de ces problèmes, et chaque tir de charges montrent un nouveau problème…

Mais quand tout est bien réglé, c’est à dire que l’ensemble des composants de la solution est bien paramétré, avec de la logique, et bien le tir de charges se passe à merveille !

./