Avez-vous des problèmes de performance ?

Publié le 2 juin 2020
Thibault LABRUT
Architecte Technique Senior
scroll
depannagea0007c-1
N’oubliez pas
de partager
cet article

Quand la crise sanitaire impacte les performances de nos applications

La crise sanitaire que nous vivons met à rude épreuve les systèmes d’informations et notamment des composants d’infrastructures plus sollicités qu’en temps normal.

Les services de connexion à distance ou les applications exposées sur internet doivent supporter une très forte hausse de charge d’activité et n’ont pas toujours une architecture et des briques d’infrastructures adaptées.

Ceci engendre dans le meilleur des cas quelques ralentissements et dans les situations extrêmes un arrêt de service.

Les systèmes d’informations étant de plus en plus complexes et les services d’infrastructure toujours plus connectés, il est souvent difficile de déterminer les causes de ces problèmes de performances.

Trop souvent les fournisseurs des solutions vont jouer sur le fait qu’aucun SLA n’a été contractualisé ou bien rejeter la faute sur un autre service d’infrastructure (qui n’a jamais entendu dire que c’était la faute du réseau ?).

Et finalement le client aura perdu du temps, de l’argent et la confiance des utilisateurs.

Adoptons une démarche plus scientifique

Analyser, détecter et corriger des problèmes de performances n’est pas chose aisée et nécessite une approche méthodique et une expertise technique. Pour chaque composant d’architecture nous allons regarder l’activité (nombre d’utilisateurs connectés, nombre de factures saisies…), les ressources (le processeur, la mémoire, les E/S, …) et les niveaux de service (temps de réponse, temps d’attente, temps d’exécution, …).

A partir de ces indicateurs nous pourrons croiser les données pour en extraire des ratios qui mettront en lumière l’impact du nombre d’utilisateurs sur la charge processeur ou le nombre de factures saisies avec le temps d’exécution d’un traitement.

Prenons l’exemple d’un client qui utilise l’application de comptabilité « Lambda ». Cette application est architecturée de manière assez classique avec un service de présentation, un service de traitement et un service d’accès aux données.

En temps normal les utilisateurs de cette application observent parfois des difficultés à consulter certains rapports mais pas au point d’impacter véritablement leur journée de travail.

Après la mise en confinement de la population, l’entreprise a pris la décision de réduire l’activité du service de comptabilité à 2 jours par semaine, spécifiquement les lundi et mardi et en télétravail.

Dès lors l’application Lambda est devenue selon les utilisateurs « inutilisable ». D’après eux la génération des rapports fonctionne uniquement tôt le matin ou tard le soir mais jamais en journée.

Objectivons le ressenti utilisateur

Commence alors le processus de recherche et de résolution du problème.

La première chose à faire est d’objectiver le ressenti utilisateur et traduire celui-ci en un indicateur mesurable et vérifiable.

Ce besoin d’objectivation s’explique par le fait que dans le cas du travail à distance tout le monde n’est pas desservi par le même réseau internet (ADSL, 4G, fibre…). De ce fait l’expérience utilisateur est de facto différente pour chacun. De plus ces mesures seront nécessaires pour ouvrir une alerte chez l’éditeur.

Si le client dispose d’un outil de surveillance et de métrologie, cette démarche de collecte d’informations sera facilitée. Nous pourrons alors requêter l’outil ou consulter les rapports disponibles pour rechercher les temps de réponse des pages ou alors les erreurs d’affichage.

Dans le cas contraire il faudra consulter les journaux d’activités des services de présentation et de traitements, voire mesurer manuellement le temps de réponse des pages (soit avec des extensions type Page Performance Test de Mozilla soit avec un chronomètre).

Analysons le problème

Une fois le problème objectivé, il faut désormais analyser le problème pour en trouver l’origine.

Après l’ouverture d’un ticket chez l’éditeur celui-ci à préconiser de doubler les ressources processeur et mémoire des serveurs web et applicatifs et de faire de même pour le JVM hébergée sur le serveur d’applications.

Après la mise en place de ces « optimisations la génération de rapport fonctionne mais il faut parfois attendre plus d’une heure pour qu’ils s’affichent.

La bonne approche est de considérer l’application dans son ensemble. En effet, pour fonctionner, une application consomme une multitude de services d’infrastructure, quelque soit le mode d’hébergement (Cloud ou On Premise) comme notamment le socle logique (VM sur site, instance de calcul dans le cloud), la base de données, le stockage, le réseau.

Se lancer dans une analyse simple des performances au niveau de l’application, c’est certainement passer à côté de la véritable cause du problème.

Il faut donc entreprendre une analyse transverse (encore plus indispensable dans un contexte Cloud, surtout hybride !) pour disposer d’une vision globale des performances à un instant t.

Cette analyse peut se faire par exemple en activant les outils à disposition (ex : perfstat pour Windows, sar pour linux, AWS Cloudwatch, Azure Log Analytic,…).

L’important est d’avoir une mesure d’indicateurs pertinents et vérifiables sur chaque service d’infrastructure et sur une période identique.

Là encore, la présence d’un outil de surveillance permettra un gain de temps évident.

Exemple d’analyse

Prenons une approche « top-down » pour analyser le problème.

Tout d’abord il est intéressant d’observer le nombre de connexions à l’application sur la journée et plus spécifiquement le nombre de connexions simultanées. Ces données sont généralement référencées dans une table de la base de données ou dans les journaux  applicatifs.

Dans notre cas, précisément le fait que les utilisateurs travaillent uniquement 2 jours par semaine augmente fortement la charge supportée de l’application à un instant donné.

Certes l’activité globale a diminué en raison de la crise sanitaire mais les chiffres le démontre avec une augmentation de 50% en moyenne de la charge avec des pics à près de 70%, à cause de la concentration des accès.

En effet ce qui pouvait être réalisé sur une période de 5 jours est maintenant concentré sur 2 jours uniquement. Cette constatation nous permet déjà de suspecter la raison du dysfonctionnement apparu après la mise en place du travail à temps partiel.

Descendons maintenant au niveau du service de traitement.  Cette application est développée en java (on le verra plus tard mais elle aurait été développée en C# ou tout autre langage objet le problème aurait été le même).

Au niveau du serveur d’applications nous allons rechercher d’éventuelles erreurs de communication avec la base de données mais aussi l’activité mémoire.

En effet qui dit java dit JVM. Nous regarderons donc spécifiquement l’action du Garbage Collector et notamment sa fréquence d’exécution (trop souvent et alors on perd en temps de réponse, trop rarement et alors on consomme la mémoire disponible !).

Et nous analyserons également la taille des objets générés car elle peut avoir une incidence sur l’affichage des pages. Dans notre cas, ce dernier indicateur nous montre que lors de la génération d’un rapport, la taille de l’objet data est tellement important que sans cette augmentation de mémoire préconisée par l’éditeur, la mémoire consommée par la JVM ne serait pas suffisante.

Nous constatons également qu’une fois que l’objet est implémenté dans la page, l’affichage se fait immédiatement. De plus lorsque l’on regarde les journaux avant l’optimisation, nous observons énormément d’OutOfMemory.

Donc, nous suspectons fortement la génération de cet objet comme la cause du problème constaté sur la production des rapports. Vous me direz « OK mais pourquoi fonctionnaient-ils très bien avant ? ».

Tout simplement parce qu’en temps normal l’activité est étalée sur une semaine et non sur deux jours.

Plus de demandes de rapports sur une même période de temps, plus de consommation mémoire et plus de risques d’OutOfMemory.

En revanche je suis d’accord sur un point : les rapports n’ont jamais mis autant de temps à s’afficher avant le début du confinement. Patience, nous verrons l’explication un peu plus tard !

Poussons encore un peu plus notre analyse

Revenons à la communication avec la base de données. Dans les journaux nous n’observons pas d’erreur particulière. Nous pourrions nous arrêter là mais pas de ça chez nous !

Passons désormais au niveau de la base de données et recherchons notamment la requête qui est appelée pour générer les rapports. Une brève analyse du top 10 des requêtes désigne une requête qui remonte plus d’un million de lignes.

Celle-ci correspond parfaitement au code exécuté par le serveur d’applications lors de la génération des rapports. Les principaux problèmes de cette requête sont qu’elle lit dans leur intégralité les plus grosses tables de la base de données et qu’elle n’est pas variabilisée ce qui empêche celle-ci d’être mise en cache.

Une réécriture de la requête est donc nécessaire pour réduire le nombre de données remontées, modifier son plan d’exécution et réduire son temps d’exécution…Bref gagner du temps.

La taille de l’objet « data » observée au niveau du serveur d’applications s’explique maintenant parfaitement. De plus l’analyse des statistiques avant le confinement montre que la taille des objets consultés par cette requêtes a augmenté de 40% suite à l’intégration en masse de nouvelles données (tiens, personne ne l’avait signalé …).

L’allongement de la génération du rapport s’explique finalement par un simple effet de seuil régulièrement constaté dans ce type d’application.

Il va de soit que nous avons également observé l’activité réseau en entrée du système d’informations et entre chaque composant d’architecture. Je n’en ai pas fait état parce que nous n’avons pas trouvé d’anomalies particulières.

Pour conclure : une démarche quotidienne, systématique et outillée, avec un accompagnement dans la durée

Comme nous l’avons vu, une analyse transverse de l’application a permis de trouver l’origine du problème et de trouver des optimisations viables dans le temps contrairement à celles préconisées par l’éditeur.

Dans notre cas la réécriture de la requête a permis de résoudre le problème et de rétablir les ressources processeur et mémoire consommées à d’origine.

Avec une approche méthodique, objective et indépendante, la détection et la résolution des problèmes de performances peuvent se faire sans installation d’outils particuliers.

En revanche il est certain qu’avec un outil de détection et de surveillance adapté comme Dynatrace, Datadog, AppDynamics, SignalFX (et j’en passe), l’analyse et la résolution auraient été grandement facilitées, et si ce n’est évitées au moins déclenchées en charge dès les premiers dysfonctionnements.

C’est pour cela qu’en plus d’une sensibilisation à notre méthode d’analyse et de diagnostic nous préconisons toujours à nos clients de considérer les performances applicatives dans leur ensemble et tout au long du cycle de vie d’une application.

En effet les performances sont à prendre en compte dès la conception de l’application avec la mise en place de collecteurs intégrés dans le code, de journaux d’activité orientés sur les performances mais aussi lors de l’implémentation avec la réalisation de tests de charge, et enfin en production avec la surveillance des différents composants sous un angle performances.

Tout ceci n’est pas simple ou inné ! L’expérience de consultants et d’architectes maîtrisant à la fois la démarche et les outils est indispensable pour mettre en place un système de surveillance performant et pérenne, indispensable au bon fonctionnement d’un SI d’autant plus lorsque celui-ci est hébergé sur des plateformes différentes On-Premise et/ou dans le Cloud !