Analyse comparative de la latence HTTP avec wrk sous Ubuntu 14.04

introduction

Cet article porte sur un outil d’analyse comparative HTTP à code source ouvert appelé wrk, qui mesure la * latence * de vos * services * HTTP * à des charges élevées *.

Latency fait référence à l’intervalle de temps entre le moment où la demande a été faite (par wrk) et le moment où la réponse a été reçue (du service). Ceci peut être utilisé pour simuler le temps de latence qu’un visiteur verrait sur votre site lors de sa visite à l’aide d’un navigateur ou de toute autre méthode d’envoi de requêtes HTTP.

wrk est utile pour tester tout site Web ou toute application reposant sur HTTP, tels que:

  • Rails et d’autres applications Ruby

  • Express et d’autres applications JavaScript

  • Applications PHP

  • Sites Web statiques fonctionnant sur des serveurs Web

  • Sites et applications situés derrière des équilibreurs de charge, tels que Nginx

  • Votre couche de cache

Les tests * ne peuvent pas être comparés à des * utilisateurs réels *, mais ils devraient vous donner une * bonne * estimation * de la latence attendue afin que vous puissiez mieux planifier votre infrastructure. Les tests peuvent également vous donner un aperçu des goulots d’étranglement liés à vos performances.

wrk est open source et peut être trouvé sur GitHub.

Très stable, il permet de simuler des charges élevées grâce à sa nature multithread. La plus grande fonctionnalité de wrk est sa capacité à intégrer les scripts Lua, ce qui ajoute de nombreuses possibilités, notamment:

  • Analyse comparative des demandes avec des cookies

  • Reporting personnalisé

  • Analyse comparative de plusieurs URL - l’outil http://httpd.apache.org/docs/2.2/programs/ab.html [+ ab +], l’outil de référence du serveur HTTP Apache, ne peut pas

Conditions préalables

L’infrastructure que nous allons utiliser lors de ce tutoriel est présentée dans le diagramme ci-dessous:

image: https: //assets.digitalocean.com/articles/wrk-ubuntu14.04/wrk-application-overview.png [Vue d’ensemble de l’infrastructure]

Comme vous pouvez le constater, nous allons utiliser wrk dans un scénario très simple. Nous allons analyser une application Express sur Node.js.

Nous allons faire tourner * deux Droplets *: un pour wrk, qui génère la charge, et l’autre pour l’application. S’ils étaient sur la même case, ils se disputeraient les ressources et nos résultats ne seraient pas fiables.

La machine pour laquelle les tests de performance doivent être suffisamment puissants pour gérer le système sollicité, mais dans notre cas l’application est si simple que nous allons utiliser des machines de la même taille.

  • Spin up deux gouttelettes dans la * même région *, car ils vont communiquer par IP privée

  • Appelez Droplet * wrk1 * et l’autre * app1 * pour suivre ce didacticiel.

  • Sélectionnez * 2 Go * de mémoire

  • Sélectionnez * Ubuntu 14.04 *

  • Sélectionnez * Réseau privé * dans la section * Paramètres disponibles *

  • Créez un utilisateur sudo sur chaque serveur

Les petites gouttelettes fonctionneront aussi, mais vous devez vous attendre à plus de latence dans les résultats du test. Dans un environnement de test réel, votre serveur d’applications doit avoir la même taille que celle que vous souhaitez utiliser en production.

image: https: //assets.digitalocean.com/articles/wrk-ubuntu14.04/do-setup-infrastructure-with-notes.png [Aperçu de la configuration de l’infrastructure océanique numérique]

Si vous avez besoin d’aide pour configurer Droplets, veuillez consulter https://www.digitalocean.com/community/tutorials/how-to-create-your-first-digital- cean-droplet-virtual-server[cet article].

Étape 1 - Les deux serveurs: Installez Docker

Pour nous faciliter la vie, nous utiliserons Docker afin de pouvoir démarrer wrk et notre application dans des conteneurs. Cela nous permet d’ignorer la configuration d’un environnement Node.js, de modules npm et de paquets deb; tout ce dont nous avons besoin est de télécharger et d’exécuter le conteneur approprié. Le temps économisé sera investi dans l’apprentissage de l’apprentissage.

Si vous ne connaissez pas Docker, vous pouvez en lire une introduction à l’adresse suivante: https://www.digitalocean.com/community/tutorials/the-docker-ecosystem-an-introduction-to-common-components&ici].

  • Remarque: * Les commandes de cette section doivent être exécutées sur * les deux Droplets *.

Pour installer Docker, connectez-vous à vos serveurs et exécutez les commandes suivantes. Tout d’abord, mettez à jour les listes de paquets:

sudo apt-get update

Installez Wget et cURL:

sudo apt-get install -y wget curl

Téléchargez et installez Docker:

sudo wget -qO- https://get.docker.com/ | sh

Ajoutez votre utilisateur au groupe + docker + afin de pouvoir exécuter les commandes Docker sans sudo:

sudo gpasswd -a ${USER} docker
sudo service docker restart
newgrp docker

Pour vérifier que + docker est installé correctement, utilisez cette commande:

docker --version

Vous devriez obtenir la sortie suivante ou similaire:

OutputDocker version 1.7.1, build 786b29d

Étape 2 - Préparer l’application de test

Exécutez ces commandes sur le * app1 * Droplet.

À des fins de test, l’auteur a publié un Docker image dans le registre public de Docker. Il contient une application de débogage HTTP écrite en Node.js. Ce n’est pas une performance (nous n’avons pas battu de record aujourd’hui), mais c’est suffisant pour les tests et le débogage. Vous pouvez consulter le code source here.

Bien entendu, dans un scénario réel, vous souhaiterez tester votre propre application.

Avant de lancer l’application, sauvegardons l’adresse IP privée de Droplet dans une variable appelée + APP1_PRIVATE_IP +:

export APP1_PRIVATE_IP=$(sudo ifconfig eth1 | egrep -o "inet addr:[^ ]*" | awk -F ":" '{print $2}')

Vous pouvez afficher l’adresse IP privée avec:

echo $APP1_PRIVATE_IP

Sortie:

Output

Votre adresse IP privée sera différente, veuillez donc en prendre note.

Vous pouvez également obtenir l’adresse IP privée depuis le panneau de configuration digitalocean.com. Choisissez simplement votre gouttelette puis accédez à la section * Paramètres * présentée dans l’image ci-dessous:

image: https: //assets.digitalocean.com/articles/wrk-ubuntu14.04/do-get-private-ip-with-notes.png [L’adresse IP privée de Drop Ocean pour Digital Ocean]

Maintenant démarrez l’application simplement en exécutant cette commande:

docker run -d -p $APP1_PRIVATE_IP:3000:3000 --name=http-debugging-application czerasz/http-debugger

La commande ci-dessus téléchargera d’abord l’image Docker requise, puis exécutera un conteneur Docker. Le conteneur est démarré dans detached mode, ce qui signifie simplement qu’il s’exécutera en arrière-plan. L’option + -p $ APP1_PRIVATE_IP: 3000: 3000 + transfère tout le trafic vers et depuis le conteneur local sur le port + 3000 +, et vers et depuis l’adresse IP privée de l’hôte sur le port + 3000 +.

Un diagramme ci-dessous décrit cette situation:

image: https: //assets.digitalocean.com/articles/wrk-ubuntu14.04/debugging-application-container-overview.png [Débogage de la visualisation du conteneur d’application]

Maintenant, testez avec + curl + pour voir si l’application est en cours d’exécution:

curl -i -XPOST http://$APP1_PRIVATE_IP:3000/test -d 'test=true'

Production attendue:

OutputHTTP/1.1 200 OK
X-Powered-By: Express
X-Debug: true
Content-Type: text/html; charset=utf-8
Content-Length: 2
ETag: W/"2-79dcdd47"
Date: Wed, 13 May 2015 16:25:37 GMT
Connection: keep-alive

ok

L’application est très simple et ne renvoie qu’un message + ok +. Donc chaque fois que wrk demande cette application, il recevra un petit message + ok +.

La partie la plus importante est que nous pouvons voir quelles demandes sont faites par wrk à notre application en analysant les journaux de l’application.

Affichez les journaux de l’application à l’aide de la commande suivante:

docker logs -f --tail=20 http-debugging-application

Votre exemple de sortie devrait ressembler à ceci:

Output[2015-05-13 16:25:37] Request 1

POST/1.1 /test on :::3000

Headers:
- user-agent: curl/7.38.0
- host: 0.0.0.0:32769
- accept: */*
- content-length: 9
- content-type: application/x-www-form-urlencoded

No cookies

Body:
test=true

Vous pouvez laisser cette tâche en marche pendant que vous exécutez vos tests de performance, si vous le souhaitez. Quittez la queue avec + CTRL-C +.

Étape 3 - Installez wrk

Connectez-vous au serveur * wrk1 * et préparez-vous à installer wrk.

Depuis que nous avons Docker, c’est très facile. Il suffit de télécharger l’image https://registry.hub.docker.com/u/williamyeh/wrk/ [+ williamyeh / wrk +] à partir du hub de registre Docker avec cette commande:

docker pull williamyeh/wrk

La commande ci-dessus télécharge une image Docker contenant wrk. Nous n’avons pas besoin de construire wrk, ni d’installer de paquet supplémentaire. Pour exécuter wrk (à l’intérieur d’un conteneur), il suffit de démarrer un conteneur basé sur cette image, ce que nous ferons bientôt.

Le téléchargement ne devrait prendre que quelques secondes car l’image est très petite (moins de 3 Mo). Si vous souhaitez installer wrk directement sur votre distribution Linux préférée, visitez cette page wiki et suivez les instructions.

Nous allons également définir la variable + APP1_PRIVATE_IP + sur ce serveur. Nous avons besoin de l’adresse IP privée du * app1 * Droplet.

Exportez la variable avec:

export APP1_PRIVATE_IP=

N’oubliez pas de changer l’adresse IP ++ en votre adresse IP privée de * app1 * Droplet. Cette variable sera uniquement enregistrée dans la session en cours. N’oubliez donc pas de la redéfinir lors de votre prochaine connexion pour utiliser wrk.

Étape 4 - Exécuter un test de référence wrk

Dans cette section, nous verrons enfin wrk en action.

Toutes les commandes de cette section doivent être exécutées sur le droplet * wrk1 *.

Voyons les options disponibles pour nous. L’exécution du conteneur wrk avec uniquement l’indicateur + - version + affichera un bref résumé de son utilisation:

docker run --rm williamyeh/wrk --version

Sortie:

Outputwrk 4.0.0 [epoll] Copyright (C) 2012 Will Glozer
Usage: wrk <options> <url>
 Options:
   -c, --connections <N>  Connections to keep open
   -d, --duration    <T>  Duration of test
   -t, --threads     <N>  Number of threads to use

   -s, --script      <S>  Load Lua script file
   -H, --header      <H>  Add header to request
       --latency          Print latency statistics
       --timeout     <T>  Socket/request timeout
   -v, --version          Print version details

 Numeric arguments may include a SI unit (1k, 1M, 1G)
 Time arguments may include a time unit (2s, 2m, 2h)

Maintenant que nous avons une bonne vue d’ensemble, composons la commande pour exécuter notre test. Notez que cette commande ne fait rien pour le moment, car nous ne l’exécutons pas à partir du conteneur.

Le cas le plus simple que nous pourrions utiliser avec wrk est:

wrk -t2 -c5 -d5s -H 'Host: example.com' --timeout 2s http://$APP1_PRIVATE_IP:3000/

Ce qui signifie:

  • + -t2 +: Utilisez * deux * threads séparés *

  • + -c5 +: Ouvrir * six connexions * (le premier client est zéro)

  • + -d5s +: Lancer le test pendant * cinq secondes *

  • + -H 'Host: example.com' +: Passer un en-tête + Host + * *

  • + - timeout 2s +: définit un * délai d’inactivité de deux secondes *

  • + http: // $ APP1_PRIVATE_IP: 3000 / + L’application cible écoute le + $ APP1_PRIVATE_IP: 3000 +

  • Benchmark le chemin + / + de notre application

Cela peut également être décrit comme six utilisateurs qui demandent notre page d’accueil à plusieurs reprises pendant cinq secondes.

L’illustration ci-dessous montre cette situation:

image: https: //assets.digitalocean.com/articles/wrk-ubuntu14.04/wrk-architecture-structure.png [structure d’architecture wrk]

  • Voici la commande réelle pour le test: *

Exécutons le scénario décrit dans notre conteneur wrk Docker:

docker run --rm williamyeh/wrk -t2 -c5 -d5s -H 'Host: example.com' --timeout 2s http://$APP1_PRIVATE_IP:3000/

Attendez quelques secondes que le test soit exécuté et examinez les résultats, que nous analyserons à la prochaine étape.

Étape 5 - Évaluer le résultat

Sortie:

OutputRunning 5s test @ http://10.135.232.163:3000
 2 threads and 5 connections
 Thread Stats   Avg      Stdev     Max   +/- Stdev
   Latency     3.82ms    2.64ms  26.68ms   85.81%
   Req/Sec   550.90    202.40     0.98k    68.00%
 5494 requests in 5.01s, 1.05MB read
Requests/sec:   1096.54
Transfer/sec:    215.24KB
  • Récapitulatif de la configuration actuelle:

    Running 5s test @ http://10.135.232.163:3000
     2 threads and 5 connections

    + Ici, nous pouvons voir un bref résumé de notre configuration de référence. Le benchmark a pris 5 secondes, l’IP de la machine référencé est «+ 10.135.232.163 +» et le test a utilisé deux threads.

  • Paramètres de distribution normaux pour les statistiques de latence et de req / s:

    Thread Stats   Avg      Stdev     Max   +/- Stdev
     Latency     3.82ms    2.64ms  26.68ms   85.81%
     Req/Sec   550.90    202.40     0.98k    68.00%

    + Cette partie nous montre les détails de la distribution normale pour notre benchmark - quels paramètres aurait une fonction Gaussian. + Les benchmarks n’ont pas toujours une distribution normale, c’est pourquoi ces résultats peuvent être trompeurs. Il faut donc toujours regarder les valeurs * Max * et * + / - Stdev *. Si ces valeurs sont élevées, alors vous pouvez vous attendre à ce que votre distribution ait une queue lourde.

  • Statistiques sur les numéros de demande, les données transférées et le débit:

     5494 requests in 5.01s, 1.05MB read
    Requests/sec:   1096.54
    Transfer/sec:    215.24KB

    + Nous voyons ici que pendant le temps de + 5.01 + secondes, wrk pourrait faire des requêtes + 5494 + et transférer + 1,05 Mo + de données. Combiné avec un calcul simple (+ nombre total de requêtes / durée de test), nous obtenons le résultat de` + 1096.54 + `requêtes par seconde.

En règle générale, plus vous définissez de clients, moins vous devriez recevoir de demandes par seconde. La latence augmentera également. En effet, l’application sera soumise à une charge plus lourde.

  • Quels sont les meilleurs résultats? *

Votre objectif est de garder le + Requests / sec + aussi haut que possible et le + Latency + aussi bas que possible.

Idéalement, la latence ne devrait pas être trop élevée, du moins pour les pages Web. La limite de temps de chargement d’une page avec des ressources est optimale lorsqu’elle est d’environ * deux secondes * ou moins.

Maintenant, vous vous demanderez probablement: Est-ce que +550.90 Requests / sec + avec une latence de + 3.82ms + est un bon résultat? Malheureusement, il n’y a pas de réponse facile. Cela dépend de nombreux facteurs tels que:

  • Nombre de clients, comme nous en avons discuté auparavant

  • Ressources du serveur - est-ce une grande ou une petite instance?

  • Nombre de machines desservant l’application

  • Type de votre service: s’agit-il d’un cache servant des fichiers statiques ou d’un serveur de publicité servant des réponses dynamiques?

  • Type de base de données, taille du cluster de base de données, type de connexion à la base de données

  • Type de demande et de réponse - S’agit-il d’une petite demande AJAX ou d’un gros appel d’API?

  • Et plein d’autres

Étape 6 - Prendre des mesures pour améliorer la latence

Si vous n’êtes pas satisfait de la performance de votre service, vous pouvez:

  • Réglez votre service - vérifiez votre code et voyez ce qui peut être fait plus efficacement

  • Vérifiez votre base de données pour voir si c’est votre goulot d’étranglement

  • Mettre à l’échelle verticalement - ajouter des ressources à votre machine

  • Mettre à l’échelle horizontalement - ajoutez une autre instance de votre service et ajoutez-la à l’équilibreur de charge

  • Ajouter une couche de mise en cache

Pour une discussion plus détaillée des améliorations apportées aux applications, consultez 5 façons d’améliorer votre Configuration du serveur d’applications Web de production.

Pensez à évaluer votre service après avoir appliqué les modifications qui s’y rapportent. Ce n’est qu’alors que vous pourrez être sûr que votre service s’est amélioré.

Vous pensez peut-être que s’il n’y avait pas ce truc Lua…

Simuler des requêtes HTTP avancées avec des scripts Lua

Comme wrk a un LuaJIT (compilateur Just-In-Time pour Lua) intégré, il peut être étendu à l’aide de scripts Lua. Comme mentionné dans l’introduction, cela ajoute beaucoup de fonctionnalités au travail.

Utiliser un script Lua avec wrk est simple. Il suffit d’ajouter le chemin du fichier à l’indicateur + -s +.

Comme nous utilisons wrk dans Docker, nous devons d’abord partager ce fichier avec le conteneur. Ceci peut être réalisé avec l’option + -v + de Docker.

Parties d’un script Lua pour wrk

Sous forme générique, en utilisant un script appelé + test.lua +, la commande entière pourrait ressembler à ceci:

docker run --rm -v `pwd`/scripts:/scripts williamyeh/wrk -c1 -t1 -d5s -s /scripts/test.lua http://$APP1_PRIVATE_IP:3000

Nous avons expliqué la commande wrk et ses options lors d’une étape précédente. Cette commande n’ajoute pas trop. juste le chemin du script et quelques commandes supplémentaires pour dire à Docker comment le trouver en dehors du conteneur.

Le drapeau + - rm + supprimera automatiquement le conteneur après son arrêt.

Mais savons-nous réellement comment écrire un script Lua? Ne craignez rien vous l’apprendrez facilement. Nous allons donner un exemple simple ici et vous pouvez exécuter vous-même vos scripts plus avancés.

Parlons d’abord de la structure de script prédéterminée qui reflète la logique interne de wrk. Le diagramme ci-dessous l’illustre pour un thread:

image: https: //assets.digitalocean.com/articles/wrk-ubuntu14.04/lua-cycle.png [cycle de script de Luk]

wrk effectue les phases d’exécution suivantes:

  • * Résoudre * l’adresse IP du domaine

  • Commencez par le fil * setup *

  • Effectuer la phase * de test de stress *, appelée la phase * en cours *

  • La dernière étape s’appelle simplement * fait *

Lorsque vous utilisez plusieurs threads, vous aurez une phase de résolution et une phase terminée, mais deux phases d’installation et deux phases d’exécution:

image: https: //assets.digitalocean.com/articles/wrk-ubuntu14.04/lua-cycle-threads.png [cycle de script Luk pour deux threads]

De plus, la * phase d’exécution * peut être divisée en trois étapes: * init *, * demande * et * réponse *.

image: https: //assets.digitalocean.com/articles/wrk-ubuntu14.04/lua-cycle-running-phase.png [cycle de script de Luk - phase en cours]

Selon les schémas présentés et la documentation, nous pouvons utiliser les méthodes suivantes dans un script Lua:

  • + setup (thread) +: Exécuté lorsque tous les threads ont été initialisés mais pas encore démarrés. Utilisé pour transmettre des données aux threads

  • + init (args) +: Appelé quand chaque thread est initialisé + Cette fonction reçoit des arguments de ligne de commande supplémentaires pour le script, qui doivent être séparés des arguments wrk par + - +. + Exemple:

wrk -c3 -d1s -t2 -s /scripts/debug.lua http://$APP1_PRIVATE_IP:3000 -- debug true
  • + request () +: Doit renvoyer l’objet HTTP pour chaque requête. Dans cette fonction, nous pouvons modifier la méthode, les en-têtes, le chemin et le corps + Utilisez la fonction d’assistance + work.format pour mettre en forme l’objet de la requête. + Exemple:

return wrk.format(method, path, headers, body)
  • `+ response (statut, en-têtes, corps) + +: appelé lorsque la réponse revient

  • + done (résumé, latence, requêtes) +: Exécuté lorsque toutes les requêtes sont terminées et que les statistiques sont calculées + Dans cette fonction, les propriétés suivantes sont disponibles:

Property

Description

summary.duration

run duration in microseconds

summary.requests

total completed requests

summary.bytes

total bytes received

summary.errors.connect

total socket connection errors

summary.errors.read

total socket read errors

summary.errors.write

total socket write errors

summary.errors.status

total HTTP status codes > 399

summary.errors.timeout

total request timeouts

latency.min

minimum latency value reached during test

latency.max

maximum latency value reached during test

latency.mean

average latency value reached during test

latency.stdev

latency standard deviation

latency:percentile(99.0)

99th percentile value

latency[i]

raw latency data of request i

Chaque thread a son propre contexte Lua et ses propres variables locales.

Nous allons maintenant passer à quelques exemples pratiques, mais vous pouvez trouver beaucoup plus de scripts de benchmarking utiles dans le https://github.com/wg/wrk/wrk/tree/master/scripts du projet wrk [répertoire + scripts + `].

Exemple: requêtes + POST +

Commençons par l’exemple le plus simple, où nous simulons une requête + POST.

Les requêtes + POST sont généralement utilisées pour envoyer des données au serveur. Cela pourrait être utilisé pour comparer:

  • Gestionnaires de formulaire HTML: utilisez l’adresse qui se trouve dans l’attribut + action + de votre formulaire HTML:

    <form action="/login.php">
    ...
    </form>
  • Noeuds finaux API + POST +: Si vous avez une API reposante, utilisez le noeud final où vous créez votre article:

    POST /articles

Commencez par créer un fichier + scripts / post.lua + sur le * wrk1 * Droplet.

cd ~
mkdir scripts
nano scripts/post.lua

Ajoutez-y le contenu suivant:

post.lua

wrk.method = "POST"
wrk.body   = "login=sammy&password=test"
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"

Ce script est très simple et nous n’avons encore utilisé aucune des méthodes mentionnées. Nous venons de modifier les propriétés globales de l’objet + wrk +.

Nous avons changé la méthode de requête en + POST +, ajouté quelques paramètres de connexion et spécifié l’en-tête + Content-Type + pour le type MIME utilisé par les formulaires HTML.

Avant de commencer le test, voici un diagramme pour vous aider à visualiser les relations entre le script, le conteneur Docker et le serveur d’applications:

image: https: //assets.digitalocean.com/articles/wrk-ubuntu14.04/container-overview.png [Visualisation du conteneur Docker]

Maintenant le moment de vérité - benchmarkez l’application avec cette commande (exécutez le * wrk1 * Droplet):

docker run --rm -v `pwd`/scripts:/scripts williamyeh/wrk -c1 -t1 -d5s -s /scripts/post.lua http://$APP1_PRIVATE_IP:3000

Sortie:

OutputRunning 5s test @ http://10.135.232.163:3000
 1 threads and 1 connections
 Thread Stats   Avg      Stdev     Max   +/- Stdev
   Latency     1.04ms  718.38us  12.28ms   90.99%
   Req/Sec     1.02k   271.31     1.52k    66.00%
 5058 requests in 5.00s, 0.97MB read
Requests/sec:   1011.50
Transfer/sec:    198.55KB

La sortie est similaire à celle que nous avons vue précédemment.

Notez que nous procédons à une analyse comparative avec une seule connexion. Cela correspond à une situation dans laquelle un seul utilisateur souhaite se connecter en permanence, en passant le nom d’utilisateur et le mot de passe. Ceci ne demande aucun fichier CSS, image ou JavaScript.

Pour un scénario plus réaliste, vous devez augmenter le nombre de clients et de threads tout en observant simultanément le paramètre de latence afin de voir à quelle vitesse l’application peut valider les informations d’identification de l’utilisateur.

Exemple: plusieurs chemins d’URL

Un autre besoin courant consiste à tester simultanément plusieurs chemins d’une application.

Créons un fichier nommé + paths.txt + dans un répertoire + data + et ajoutons tous les chemins que nous souhaitons utiliser lors de notre test de performance.

cd ~
mkdir data
nano data/paths.txt

Trouvez un exemple de + data / paths.txt + ci-dessous:

paths.txt

/feed.xml
/contact/
/about/
/blog/
/2015/04/21/nginx-maintenance-mode/
/2015/01/06/vagrant-workflows/
/2014/12/10/top-vagrant-plugins/

Ensuite, récupérez his script simple et enregistrez-le sous le nom + scripts / multiple-url-paths.lua +:

multiple-url-paths.lua

-- Load URL paths from the file
function load_url_paths_from_file(file)
 lines = {}

 -- Check if the file exists
 -- Resource: http://stackoverflow.com/a/4991602/325852
 local f=io.open(file,"r")
 if f~=nil then
   io.close(f)
 else
   -- Return the empty array
   return lines
 end

 -- If the file exists loop through all its lines
 -- and add them into the lines array
 for line in io.lines(file) do
   if not (line == '') then
     lines[#lines + 1] = line
   end
 end

 return lines
end

-- Load URL paths from file
paths = load_url_paths_from_file("/data/paths.txt")

print("multiplepaths: Found " .. #paths .. " paths")

-- Initialize the paths array iterator
counter = 0

request = function()
 -- Get the next paths array element
 url_path = paths[counter]

 counter = counter + 1

 -- If the counter is longer than the paths array length then reset it
 if counter > #paths then
   counter = 0
 end

 -- Return the request object with the current URL path
 return wrk.format(nil, url_path)
end

Bien que ce tutoriel n’essaye pas d’enseigner les scripts Lua en détail, si vous lisez les commentaires dans le script, vous pouvez avoir une bonne idée de ce qu’il fait.

Le script + multiple-url-paths.lua + ouvre le fichier + / data / paths.txt + et si ce fichier contient des chemins, ils sont enregistrés dans un tableau + chemins + interne. Ensuite, à chaque demande, le chemin suivant est pris.

Pour exécuter ce test de performance, utilisez la commande suivante (exécutez-la sur le * wrk1 * Droplet). Vous remarquerez que nous ajoutons des sauts de ligne pour faciliter la copie:

docker run --rm \
          -v `pwd`/scripts:/scripts \
          -v `pwd`/data:/data \
          williamyeh/wrk -c1 -t1 -d5s -s /scripts/multiple-url-paths.lua http://$APP1_PRIVATE_IP:3000

Sortie:

Outputmultiplepaths: Found 7 paths
multiplepaths: Found 7 paths
Running 5s test @ http://10.135.232.163:3000
 1 threads and 1 connections
 Thread Stats   Avg      Stdev     Max   +/- Stdev
   Latency     0.92ms  466.59us   4.85ms   86.25%
   Req/Sec     1.10k   204.08     1.45k    62.00%
 5458 requests in 5.00s, 1.05MB read
Requests/sec:   1091.11
Transfer/sec:    214.17KB

Requêtes préalables avec JSON et YAML

Vous pourriez maintenant penser que d’autres outils d’analyse comparative peuvent également effectuer ce type de test. Cependant, wrk peut également traiter des demandes HTTP avancées à l’aide du formatage JSON ou YAML.

Par exemple, vous pouvez charger un fichier JSON ou YAML qui décrit chaque demande en détail.

L’auteur a publié un exemple avancé avec une requête JSON sur du blog technique de l’auteur.

Vous pouvez analyser n’importe quel type de requête HTTP auquel vous pouvez penser, avec wrk et Lua.

Conclusion

Après avoir lu cet article, vous devriez pouvoir utiliser wrk pour évaluer vos applications. En remarque, vous pouvez également voir la beauté de Docker et comment il peut grandement réduire la configuration de votre application et de vos environnements de test.

Enfin, vous pouvez faire un effort supplémentaire avec les requêtes HTTP avancées en utilisant les scripts Lua avec wrk.