Pour rappel, dans la première partie de cette série d’articles, vous avez pu découvrir la manière dont je testais Piwam grâce à la virtualisation. Nous allons maintenant soumettre notre application à des premiers tests… de performance.
Bien que certaines applications soient faîtes pour une utilisation mono utilisateur, la plupart sont destinées à accueillir des centaines, des milliers d’utilisateurs simultanément, utilisateurs qui eux même ont la possibilité de réaliser des milliers d’interactions différentes. Comment alors tester le comportement de son application dans les pires situations, sans attendre que le chaos ne vienne s’imposer de lui même une fois l’application mise en production ? C’est le sujet de ce billet. Ce qui est présenté ci-dessous interessera les développeurs PHP mais aussi tous ceux qui utilisent une autre technologie web.
Apache AB
Commençons par faire stresser un petit peu notre application… AB, pour Apache HTTP server Benchmarking tool, permet de simuler des accès au serveur web, en exécutant le nombre de requêtes souhaité par le biais d’un certain nombre de connexions concourantes, elles aussi contrôlées. AB permet sans soucis de passer des serveurs proxy, simuler les requêtes GET comme POST, gérer l’authentification HTTP… La commande que j’utilise le plus souvent est la suivante :
> ab -e output.csv -n 10000 -c 100 http://docbook:80
Quelques explications sur les options utilisées ici :
- -e : spécifie un fichier CSV de sortie
- -c : nombre de connexions concourantes
- -n : nombre de requêtes à exécuter (réparties entre les différentes connexions)
Je vous invite à lire la très claire page de documentation pour découvrir toutes les options disponibles. Une fois exécutée, cette commande nous livre la sortie suivante :
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking docbook (be patient).....done
Server Software: Apache/2.2.9
Server Hostname: docbook
Server Port: 80
Document Path: /
Document Length: 4427 bytes
Concurrency Level: 100
Time taken for tests: 5.569 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 472500 bytes
HTML transferred: 442700 bytes
Requests per second: 17.96 [#/sec] (mean)
Time per request: 556.946 [ms] (mean)
Time per request: 55.695 [ms] (mean, across all concurrent requests)
Transfer rate: 82.85 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.2 0 1
Processing: 246 548 110.6 539 1150
Waiting: 246 547 109.9 538 1147
Total: 247 548 110.6 539 1150
Percentage of the requests served within a certain time (ms)
50% 539
66% 564
75% 578
80% 591
90% 633
95% 673
98% 1101
99% 1150
100% 1150 (longest request)
La ligne sur-lignée est à mon avis celle qui donne le plus de sens aux résultats. Le nombre de requêtes par secondes est en effet un bon indicateur de la santé de votre application (et de votre serveur). Quant au fichier CSV généré, dont on a un aperçu avec les pourcentages donnés à la fin de la sortie ci-dessus, vous pourrez y retrouver la répartition des timings dans lesquels ont été satisfaites les requêtes. Ajoutez à cela des taux de transferts, des erreurs détectées potentielles, et vous obtenez ici un bon outil de benchmarking.
Comment simuler l’envoi de données ?
Comme indiqué dans sa présentation, il est possible de simuler la soumission de formulaires via l’option -p POSTFILE. Une question très récurrente revient souvent : à quoi ressemble ce fichier POSTFILE ? En fonction de la version utilisée, la documentation d’Apache peut ne pas être très bavarde. Ce fichier comprend la liste des arguments de la manière suivante : nom=valeur&nom2=autrevaleur, avec l’encodage spécial utilisé pour les URL.
Pylot

Graphique généré par Pylot : temps de réponse en fonction du temps écoulé
Écrit en Python, Pylot possède a 2 plusieurs pour séduire : la capacité de générer des graphiques, la présence d’un GUI pour les allergiques au mode console, interfaçage XML-RPC… Pylot fonctionne par le biais de scénarios, des test-cases, écrits au sein de fichiers XML pas trop compliqués. Ce mode de fonctionnement permet de personnaliser assez facilement les scénarios et de passer tous ces test-cases automatiquement. Découvrez Pylot sur http://www.pylot.org/.
C’est trop long !
Ces tests vous ont permis de vous apercevoir d’une chose : votre application met systématiquement un minimum de 400 ms à répondre, et facilement jusqu’à 900 ms dès que plusieurs utilisateurs effectuent des recherches. Des temps qui rapidement risquent d’énerver vos utilisateurs. Comment alors réduire autant que possible ces timings fous ?
Premièrement, l’utilisation d’un accélérateur PHP peut être tout a fait adaptée (tout du moins, pour les développeurs PHP). APC, eAccelerator et consorts devraient vous intéresser. Laissez vous guider par les tests et comparatifs (un lien : iPerSec). Ces accélérateurs donneront un coup de boost magique à votre projet PHP.
Des « erreurs », ou lourdeurs de développement, peuvent être à l’origine de la lenteur de l’application. Ré-écrire et optimiser son code peut s’avérer extrêmement long. Avant ça, un petit tour vers une étape de profiling est indispensable. Pour ceux qui ne savent pas de quoi je parle, jetez un oeil sur mon article dédié à XDebug. Cette étape de profiling vous permettra de détecter une éventuelle partie de code particulièrement et anormalement consommatrice de temps.
Et finalement, si c’est encore possible, prenez le temps nécessaire pour analyser la source de la lenteur, la corriger, pratiquer le refactoring de code, installer des serveur proxy, refaire des tests plus précis, modifier la configuration PHP, etc. Un prochain article sera l’occasion d’aborder ces même tests dédiés à MySQL. Et si vous n’avez plus le temps pour corriger tout ça, et bien c’est le moment de prendre de bonnes résolutions et de mettre en place toutes les bonnes pratiques de ZeTechnology pour votre prochain projet !