Publié par
Il y a 3 années · 8 minutes · Craft

Make it work, OK. Make it right, DONE. Make it fast, euh… Ou : des tests de perf pour pas cher

Le matin, à la fin du daily meeting :

QA : « Bon, je suis venu à votre stand-up pour vous remonter que, lors des derniers tests de perf, nous avons constaté une forte hausse dans les temps de réponse de votre application. »

Quelqu’un de l’équipe : « Une hausse de combien ? »

QA : « Sur notre plateforme de tests, nous étions à 200 requêtes par seconde sur les versions précédentes de l’application. Avec la nouvelle version, nous en sommes à moins de 100. »

Quelqu’un de l’équipe : « Bon, on va prendre le point en priorité. C’est quand la mise en production ? »

QA :  «  La semaine prochaine. »

Tout le monde se regarde…

Rattraper des problèmes de performance quelques jours avant la mise en production (voire en production) arrive très souvent dans deux contextes  : quand les équipes délèguent les tests de performance à une autre équipe dédiée ; ou quand les développeurs ne font pas de test de performance du tout. Dans le premier scénario, il y a une tendance à repousser l’aspect performance vers l’extérieur de l’équipe. Dans ce cas, l’équipe n’a pas les moyens de vérifier si les derniers développements ont impacté la performance de l’application. Dans le deuxième scénario, on ne constate les dégâts d’un développement maladroit ou d’un mauvais choix de design qu’en production. Et là, c’est le drame !

La suite…

Chez notre client, nous avions 3 mois de développement avant chaque mise en production (MEP). Quelques semaines avant la MEP, les équipes déposaient leurs livrables auprès de l’équipe QA, qui menait elle de son côté des tests de performance.

Suite à la remontée de l’information lors du stand-up, un binôme (un membre de l’équipe de développement et un autre de l’équipe QA) a pris le point. Après quelques heures, quelques tirs de perf et beaucoup de profiling le problème a été identifié. La correction a été simple. Nous avons livré un correctif très rapidement et la MEP était sauvée. Par contre, suite à cet épisode, nous (équipe de développement) nous sommes rendu compte que nous n’avions jusqu’à présent aucun moyen de tester la performance de notre application en amont. A côté de ça, personne n’a vraiment apprécié devoir aller chercher les problèmes de performance en « mode cowboy » quelques jours avant la mise en production. Comment faire en sorte que cela ne se reproduise plus ?

Mettre en place des tests de performance

Nous avons donc décidé d’agir, pour moins devoir réagir (des fois j’ai des moments philosophiques) en mettant en place des tests de performance au sein de l’équipe.

Ok. Mais par où commencer ?

Première étape : choisir ce que l’on va tester

Nous avions une application backend, qui gérait l’accès aux données via une API REST. De ce fait, nous avons décidé de créer des scénarios de tests qui attaqueraient directement notre API via HTTP. En se plaçant à l’entrée (tout en haut) de notre application, nous étions sûrs que les tests allaient traverser toute notre stack technique. Cela est important, car un bug de performance peut se cacher dans le code, mais aussi dans notre système, ou plus précisément, dans la configuration de nos serveurs, bases de données, réseau, etc.

Ensuite, nous avons échangé avec l’équipe QA pour savoir quels services étaient les plus sollicités en production. De cette façon, nous pourrions distribuer notre charge de tests en fonction.

Deuxième étape : les outils

Après avoir établi notre stratégie de tests et avoir en mains les services plus sensibles d’un point de vue production, nous nous sommes mis à chercher les outils dont nous aurions besoin pour mettre en place les tests.

Nous avions une application Java classique et nous utilisions Maven pour compiler notre projet. Pour nos tests de performance, nous avons donc utilisé :

1. Jenkins pour lancer nos scénarios de test de manière automatisée ;
2. Chronos JMeter Maven Plugin pour lancer nos tests JMeter via Maven ;
3. JMeter pour exécuter nos scénarios de test ;
4. et finalement le Performance Plugin de Jenkins pour exhiber les rapports des tests.

Petit disclaimer pour éviter la bagarre dans les commentaires : il y a beaucoup d’outils autres que JMeter pour les tests de performance, chacun avec ses avantages et inconvénients. Nous avons décidé d’utiliser JMeter car : il y avait déjà des gens dans l’équipe qui le connaissait ; car c’est aussi très simple d’appréhender son usage ; et finalement car il y a des nombreux plugins et une vaste documentation sur comment l’intégrer. Donc, dans notre contexte, c’était le choix le plus avantageux en termes de coûts-bénéfices.

Finalement, tout rassembler

Je ne vais pas décrire ici le détail de l’écriture des tests JMeter ou comment configurer tel ou tel plugin. Il y a de nombreux liens sur le net où trouver ces informations. Nous allons ici nous concentrer sur l’idée générale.

Après la création des scénarios JMeter (c’est l’étape qui nous a pris le plus de temps), nous les avons testé sur notre plateforme d’intégration continue. Nous avons aussi ajusté notre temps de montée en charge (ramp-up), le nombre d’appels à chaque service (en essayant de se rapprocher de l’utilisation en production), le nombre d’utilisateurs (en fonction de notre plateforme) et le temps d’attente entre chaque appel (pour simuler un utilisateur humain).

Ensuite, nous avons ajouté nos scénarios de test dans notre projet (à côté de notre code source) et nous avons configuré le plugin Chronos de tel façon à pouvoir lancer les tests JMeter via Maven, à partir de la ligne de commandes. Nous avons isolé notre configuration de tests dans un profile Maven que nous avons appelé « perf ».

Finalement, nous avons créé un job Jenkins pour exécuter nos tests. Comme nos scénarios de test duraient environ une heure, nous avons décidé de les lancer une fois par jour, tard le soir, quand il n’y avait personne au bureau (vous imaginez bien que lorsque les tests tournaient la plateforme d’intégration continue devenait très très lente). Dans notre job Jenkins, nous avons configuré le plugin Performance pour faire échouer notre build si les temps de réponse descendaient en-dessous d’un certain seuil.

Et ça donne quoi ?

Le graphique ci-dessous illustre les premiers lancements de notre job de tests de performance. L’écart important entre la médiane (median) et la moyenne (average) est dû au fait que nous n’avions pas encore calibré le nombre d’appels de chaque service en fonction de l’usage en production. Pour la majorité des services que nous avions, les temps de réponse étaient très performants, sauf pour quelques-uns qui étaient plus gourmands. Comme les services performants étaient très nombreux et le nombre d’appels à chaque service était le même, la médiane est tirée vers le bas.

Dans le graphique on peut voir également l’évolution quotidienne des temps de réponse de nos services. Lors du build #95, par exemple, nous pouvons constater une augmentation des temps de réponse. De ce fait, nous savons que nous avons apporté une évolution dans notre application entre les builds #94 et #95 (ce qui correspond à une journée dans notre cas) qui a probablement entraîné une dégradation de la performance. Ainsi, trouver le problème va s’avérer beaucoup plus simple, car nous pouvons nous concentrer sur les commits qui ont eu lieu la veille et non pas tous les commits à partir de la dernière campagne de perf. A partir du build #95 notre job Jenkins de perf a commencé à échouer, ce qui voulait dire que nous avions de temps de réponses au dessus du seuil que nous avions établi.

Dernier point à noter. Les temps de réponse ici sont nettement moins bons qu’en production. Ici le but n’est pas d’obtenir un temps de réponse très performant, car comme il s’agit de notre plateforme d’intégration continue, le matériel n’est pas le même (étant moins dimensionné) qu’en production. Ce qui nous intéresse ici c’est la variation des temps de réponse, qui nous permettra potentiellement d’identifier des problèmes de perf.

Pour conclure

Mettre en place des tests de performance au sein de son l’équipe apporte plusieurs avantages. Premièrement, cela sensibilise les développeurs aux problématiques de performance. Ainsi l’équipe prendra plus conscience des points critiques dans le code en termes de performance et en tiendra compte lors des développements. Ensuite, les tests de perf vous aideront aussi à ne pas tomber dans la spirale négative : j’ajoute des fonctionnalités dans mon produit > le produit devient plus complexe > identifier et régler les problèmes de performance devient plus compliqué > j’ajoute des fonctionnalités…  vous aurez compris. Plus tôt on identifie des problèmes de perf, plus vite on les corrige, moins cher ça coûte.

Dernier point à noter, les tests de performance, tel que décrit ici, ne remplacent pas une vraie campagne de perf. Dans une vraie campagne de tests de performance, plusieurs types de tests sont pris en compte. D’ailleurs, ces tests sont souvent exécutés sur des plateformes iso-production, ce qui permet d’avoir une idée plus accrue du comportement de l’application en production. Dans notre cas, nous avons exécuté nos tests sur notre plateforme d’intégration continue avec, évidement, un dimensionnement moins important que par rapport celui de la production. Cependant, mettre en place une telle batterie de tests va vous donner des nouveaux indicateurs qui vous permettront de suivre de plus près la performance de vos applications, au sein de votre équipe, pour pas trop cher (en termes de temps de mise en place).

Diego Lemos
Diego s’est forgé une solide expérience dans l'écosystème Java. Depuis, longtemps convaincu par l’agilité, Diego a participé à des nombreux projets agiles, d’abord en tant que développeur, puis en tant que scrum master et ensuite coach technique. Diego dispose d’un vaste panel de compétences sur l’ensemble de l’écosystème JVM, et notamment les solutions du monde open-source.
Passionné par l’informatique, il a eu l’occasion de d’intervenir sur des missions techniques très variées, notamment en tant que en tant que développeur frontend et sysadmin. Cela fait de Diego un expert technique full stack.
Il a joué un rôle important dans des projets de grande envergure, en tant que coach technique, notamment autour de la mise en place de pratiques tels que le Continuous Delivery à l’échelle. Aujourd’hui, Diego intervient principalement en tant que formateur, consultant et coach technique sur des sujets tels que le testing, le design du code, le software craftsmanship et le continuous delivery.
Blog personnel : http://diegolemos.net
Twitter : @dlresende.

Une réflexion au sujet de « Make it work, OK. Make it right, DONE. Make it fast, euh… Ou : des tests de perf pour pas cher »

  1. Publié par gamis, Il y a 3 années

    voilà enfin un bon billet sur le blog de xebia.fr, neutre et pragmatique.
    Merci Diego, je ferai en sorte de faire de même chez mon Client.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *