Comment aborder vos problématiques de performance
Je vous propose ici un retour d'expérience sur différentes missions dont la problématique commune consiste en un manque de performances d'une application. Ce que vous trouverez ici : des conseils et points importants à garder à l'esprit pour les problématiques de performance.
Ce que vous ne trouverez pas : des références d'outils puisque leur choix dépend pour beaucoup de votre contexte. Vous n'y trouverez pas non plus de quoi conforter votre attitude face à une application prête à être mise en production si celle-ci ressemble à "jusqu'ici tout va bien.... jusqu'ici... tout va bien...". Si tel est votre cas, préparez-vous à la chute !
Considérer l'aspect performance comme il se doit...
La performance est souvent reléguée au second rang des préoccupations des responsables des applications. Ça vous paraît évident, vous souhaitez avant tout une application fonctionnelle davantage qu'une application rapide. On entend souvent dire aux développeurs : "Faites d'abord un code qui fonctionne, on l'optimisera après". Sauf qu'on ne voit jamais cet "après" pour des raisons ô combien irréfutables et indiscutables : contraintes budgétaires, planning, client ...
Et pourtant, la performance est généralement un critère pouvant tout simplement empêcher une mise en production. Vous imaginez dire calmement au responsable projet que "la chaîne batch quotidienne tourne aux petits oignons, avec des rapports détaillés... mais en 32 heures" ou encore "la recherche de contrat pour le conseiller financier en clientèle ? elle répond avec une fiche hypra-détaillée... en 6 minutes" (dans ce cas prévoir en plus du "sablier" de la page d'attente, le pitch du conseiller : "la famille, les enfants, le chien... ça va bien ?")
La performance ? On verra ça "après"...
Le premier conseil est donc de considérer le volet performance de tout projet comme un workstream à part entière, avec son planning et ses ressources dédiées. La performance doit faire partie intégrante des tests de recette et de non régression.
Intégrer ces considérations dans un projet agile reviendrait donc à ajouter à la "définition du done" la contrainte que la fonctionnalité réponde aux exigences de performance (et bien sûr ne dégrade pas celles des fonctionnalités déjà réalisées).
Impliquez vos utilisateurs
Naturellement, vous impliquez déjà vos utilisateurs pour les fonctionnalités, impliquez-les également pour les performances attendues ! Ne cherchez pas à définir leurs besoin en terme de performance à leur place tout comme vous ne le feriez pas pour les fonctionnalités.
Demandez-leur de vous indiquer leurs exigences en terme de performance mais aussi leurs cas d'utilisation et scenario typiques.
Cela vous évitera de perdre du temps à optimiser une fonctionnalité qui prend 10 secondes et n'est utilisée qu'une dizaine de fois par jour, pour vous concentrer sur celle prenant 5 secondes et utilisée plusieurs millier de fois.
Des fonctionnalités sont critiques car demandant de la réactivité comme "j'ai mon client V.I.P. au bout du fil, il me faut son état de compte en moins de 4 secondes" d'autres beaucoup moins comme "j'ai besoin d'un rapport des ventes, je peux le lancer avant la pause café et le trouver à mon retour".
Cessez de deviner leur besoin, demandez le à vos utilisateurs. Ne tombez pas non plus dans le piège des exigences ("on veut que ce soit rapide !" ou encore "que toutes les transactions répondent en moins de 2 secondes") mais préférez leur demander de placer des priorités, d'envisager un mode dégradé. Cette approche vous permettra aussi en dernier recours de connaitre les fonctions à désactivé lors d'une sur-charge (en dernier recours j'ai dit !)
Soyez professionnels, outillez-vous
Le boss : "on a des problèmes de performance en prod, il faut me corriger ça de suite" Le dev : "attendez, je regarde... clic... clic, clic... chez moi ça marche bien, vous êtes sûr ?"
J'exagère à peine la situation... car c'est malheureusement du vécu.
"If you can't measure it, you can't improve it", une citation attribuée à Lord Kelvin, qui a le mérite de donner une indication sur l'étape initiale de l'amélioration des performances : la mesure. Et la mesure outillée s'il vous plait ! pas celle à l'à-peu-prêt, technique voisine du pif-o-mètre®.
Redevenons sérieux quelques instants, vos mesures doivent évidemment se faire avec un outil, pour être fiables bien sûr mais aussi et surtout reproductibles. Si vous modifiez un bout de code ou un paramètre, il est ensuite nécessaire de reproduire votre mesure exactement de la même manière qu'avant cette modification pour pouvoir observer une différence (bonne ou mauvaise !).
Cet aspect reproductible, en plus de permettre de constater les comportements avant/après modification, vous permettra également de gagner un temps précieux s'il répond à minima à ces caractéristiques :
enregistrement d'un scénario paramétrable (si je joue toujours la même recherche avec le même profil utilisateur, je fausse la mesure en limitant mon périmètre de données accédées)
configuration de la montée en charge (pour atteindre les limites théoriques, la cible en nombre d'accès concurrents que je me suis donné, etc.)
reporting suffisamment expressif sur les temps de réponse client (les prises de mesures plus détaillées sur chaque éléments du système seront nécessaires pour la phase d'analyse poussée)
Utilisez un environnement dédié et maîtrisé
Placez-vous au plus tôt dans les conditions de productions pour faire vos tests, en utilisant impérativement un environnement dédié à ces mesures. Autant au niveau de la puissance de l'environnement que de la volumétrie des données et des accès. L'informatique a beau être une science exacte (quoique...) il n'est pas rare de se rendre compte du comportement réel qu'une fois sur l'environnement cible. Votre super-algorithme maison, si efficace sur vos environnement de test x86 Quad Core, peut se révéler être une vraie tortue sur vos machines RISC de production.
Créer un jeu de données cohérent et suffisamment volumineux pour représenter une production au bout de 6 mois, 1 an, etc. est rarement évident. Plusieurs solutions existent comme créer un injecteur dédié à cette tâche. Efficace mais coûteux !
Une astuce impliquant le principe DRY (Don't Repeat Yourself) : commencez par créer vos scenario de tests de charge automatisés, en particulier ceux concernant la création de données (en prenant soin de les paramétrer, pour créer des données suffisamment distinctes et représentatives), faites ensuite tourner ces tests de charge durant plusieurs jours/nuits, et vous obtenez une base de données alimentée, prête à l'emploi !
N'oubliez pas après chaque tir de test de charge de revenir à l'état initial (dump, snapshot, etc.) pour assurer la reproductibilité de vos tests.
Afin d'être le plus en phase possible avec les conditions de production, si certains comportements ne peuvent vraiment pas être reproduits, contentez-vous de les simuler. Par exemple, si votre application est à destination de client via Internet ou un WAN, ajoutez à votre environnement de test un proxy chargé d'ajouter une latence réseau configurable.
Afin d'anticiper l'accroissement de volumétrie et les temps de réponse associés, faites vos projections par exemple à 6 mois, 1 an, 2 ans et créez-vous une base de référence pour chaque. Cela vous permettra, en réalisant vos tests sur chacune, d'évaluer la progression de vos performances : linéaire, exponentielle, parabolique (?!)
Vous êtes pleins de bonnes intentions... continuez !
Voilà, vous avez trouvé les goulets d'étranglement les plus importants et vos mesures sont rassurantes, vous pouvez passer en production, bravo ! Mais ne vous arrêtez pas en si bon chemin, poursuivez votre effort : gardez vos métriques et KPI principales, celles n'introduisant pas d'overhead important et permettant tout de même une bonne vision des performances, et continuez à mesurer vos performances en production.
En plus de vous faire briller en affichant vos mesures sur du concret, de la "vraie" production, cela vous permettra d'anticiper les prochains goulets d'étranglement et surtout valider les hypothèses de charges et volumes qui vous ont été donnés ou que vous avez calculé et les confronter à "la vraie vie".