J'ai eu récemment à tester un service
Précisons bien le cahier des charges : le service à tester était
du
On peut tester les performances d'un serveur HTTP simplement avec
J'ai trouvé six outils différents, et voici mon expérience. Mais
d'abord quelques notes générales si vous n'avez pas l'habitude de ce
genre d'outils de test :
Maintenant, les différents outils. On commence par le vénérable
ApacheBench
(alias ab). Largement disponible, son utilisation de base est :
ab -n 5000 -c 100 http://tested.example.org/
Le
Time taken for tests: 8.536 seconds
Complete requests: 5000
Failed requests: 0
Requests per second: 585.74 [#/sec] (mean)
Time per request: 170.724 [ms] (mean)
Time per request: 1.707 [ms] (mean, across all concurrent requests)
Connection Times (ms)
min mean[+/-sd] median max
Connect: 5 93 278.9 39 3106
Processing: 5 65 120.1 43 1808
Waiting: 4 64 120.2 43 1808
Total: 14 158 307.9 87 3454
Percentage of the requests served within a certain time (ms)
50% 87
66% 104
75% 123
80% 130
90% 247
95% 1027
98% 1122
99% 1321
100% 3454 (longest request)
Le serveur a bien tenu, aucune connexion n'a échoué. D'autre part,
on voit une forte dispersion des temps de réponse (on passe par
l'Internet, ça va et ça vient ; en local - sur la même machine, la
dispersion est bien plus faible). Le taux de requêtes obtenu (586
requêtes par seconde) dépend fortement du parallélisme. Avec
ab affiche des messages d'erreur dès que le serveur HTTP en face
se comporte mal, par exemple en fermant la connexion tout de suite
(«
Par défaut, ab ne réutilise pas les connexions HTTP. Si on veut
des connexions persistentes, il existe une option
Deuxième logiciel testé, Siege (j'en profite
pour placer le mot de
% siege -c 100 -r 50 http://tested.example.org/
Transactions: 5000 hits
Availability: 100.00 %
Elapsed time: 5.09 secs
Response time: 0.07 secs
Transaction rate: 982.32 trans/sec
Concurrency: 66.82
Successful transactions: 5000
Failed transactions: 0
Longest transaction: 3.05
Shortest transaction: 0.00
(Le nombre de requêtes, donné avec
Transactions: 5000 hits
Availability: 100.00 %
Elapsed time: 0.92 secs
Response time: 0.02 secs
Transaction rate: 5434.78 trans/sec
Concurrency: 85.12
Successful transactions: 5000
Failed transactions: 0
Longest transaction: 0.46
Shortest transaction: 0.00
Si vous augmentez le niveau de parallélisme, vous aurez peut-être
le message d'erreur :
WARNING: The number of users is capped at 255. To increase this
limit, search your .siegerc file for 'limit' and change
its value. Make sure you read the instructions there...
Il faut alors éditer le fichier de configuration (qui ne s'appelle
pas
Siege a aussi des
problèmes de robustesse et vous sort des messages comme
«
Notons que Siege permet d'analyser le
Troisième logiciel testé, JMeter. Contrairement à
ApacheBench et Siege où tout était sur la ligne de commande et où on
pouvait démarrer tout de suite, JMeter nécessite de d'abord définir
un
Quatrième logiciel, Cassowary. Contrairement
aux trois précédents, il n'était pas en
git clone https://github.com/rogerwelin/cassowary.git
cd cassowary
go build ./cmd/cassowary
Et on y va :
% ./cassowary run -u http://tested.example.org/ -n 5000 -c 100
TCP Connect.....................: Avg/mean=17.39ms Median=16.00ms p(95)=36.00ms
Server Processing...............: Avg/mean=15.27ms Median=13.00ms p(95)=22.00ms
Content Transfer................: Avg/mean=0.02ms Median=0.00ms p(95)=0.00ms
Summary:
Total Req.......................: 5000
Failed Req......................: 0
DNS Lookup......................: 8.00ms
Req/s...........................: 5903.26
Par défaut, Cassowary réutilise les connexions HTTP, d'où le taux de
requêtes élevé (on peut changer ce comportement avec
Cinquième logiciel utilisé, k6. Également écrit en
% go get go.k6.io/k6
package hash/maphash: unrecognized import path "hash/maphash" (import path does not begin with hostname)
package embed: unrecognized import path "embed" (import path does not begin with hostname)
Les deux derniers logiciels sont, je crois, les plus riches et
aussi les plus complexes. D'abord, le sixième que j'ai testé, Gatling. On le télécharge, on
% ./bin/recorder.sh
Il fait tourner un
% export http_proxy=http://localhost:8000/
% curl http://tested.example.org/
Et Gatling enregistrera une requête HTTP vers
% ./bin/gatling.sh
Et on a une jolie page
Enfin, le septième et dernier, Locust. (Après le champ lexical de
la guerre, avec Siege et Gatling, celui d'une
from locust import HttpUser, task
import requests
class HelloWorldUser(HttpUser):
@task
def hello_world(self):
self.client.get("/")
self.client.get("/hello")
Une fois le plan écrit, on peut lancer Locust en ligne de commande :
% locust --host http://tested.example.org --headless --users 100 --spawn 10
On ne peut pas indiquer le nombre maximal de requêtes (seulement le
temps maximal), il faut
interrompre le programme au bout d'un moment. Il affiche alors :
Name # reqs # fails | Avg Min Max Median | req/s failures/s
------------------------------------------------------------------------------------------------------------------------------------------------
GET / 20666 0(0.00%) | 87 7 541 94 | 736.70 0.00
On voit que le nombre de requêtes par seconde est faible. Une des
raisons est que Locust est très consommateur de temps de
processeur : celui-ci est occupé à 100 % pendant l'exécution, et est
le facteur limitant. Locust avertit, d'ailleurs, «
Mais l'intérêt de Locust est de lancer un serveur Web qui permet
d'obtenir de jolis graphes :
On peut aussi utiliser cette interface Web pour piloter les tests.
En conclusion ? Je ne crois pas qu'il y ait un de ces logiciels qui fasse tout ce que je voulais et comme je voulais. Donc, j'en garde plusieurs.