[Nantes JUG] Stresser vos applications web avec Gatling

Le 17 novembre dernier avait lieu une soiré JUG Nantes sur Gatling, présentée par Rossi Oddet. Vous avez besoin de faire des tests de charge sur votre application web et vous ne savez pas comment faire ? Ou bien vous avez testé JMeter et vous en avez encore des cauchemars ? Gatling est sûrement ce qu’il vous manque… Voici un rapide compte-rendu de la session.

Rossi nous a présenté cinq bonnes raisons d’utiliser Gatling :

  • sa prise en main facile : bien que basé sur scala, il n’est pas nécessaire de connaître ce langage ni même la programmation fonctionnelle pour l’utiliser. Il est aisé d’écrire un scénario (c’est-à-dire le comportement d’un utilisateur). On greffe sur ce scénario une politique d’injection (nombre d’utilisateurs, arrivée simultanée ou non), et ça roule.
  • sa performance : avec JMeter, un utilisateur correspond à un thread, ce qui le rend très gourmand en ressources. Gatling utilise l’asynchronicité, ce qui lui permet de simuler le comportement de nombreux utilisateurs sans difficulté. Il est même possible de continuer à utiliser sa machine pendant des tests Gatling !
  • son intégration officielle avec Maven, Jenkins, Graphite. Il est possible également de l’intégrer avec Play et Gradle.
  • sa mailing-list active ;
  • une bonne activité sur Github.

Ces avantages sont également visibles sur le support de la présentation.

Nous avons ensuite suivi une démonstration de l’utilisation de Gatling. L’installation est très simple, puisqu’il s’agit d’un zip à extraire à l’endroit désiré. Deux exécutables sont présents : gatling permet d’exécuter les scénarios, et recorder est un outil graphique pour enregistrer les scénarios. *Recorder *est pratique pour débuter ; cependant, les scénarios générés comportent parfois des erreurs et il est nécessaire de les relire. Ils sont aisés à comprendre et à manipuler, et à la longue, on apprend à les créer soi-même sans passer par le recorder.

Une manière de créer un scénario avec recorder est de lui transmettre un fichier de type har. Il est facile de créer ce fichier en utilisant les outils de développement de Chrome. Aller dans Network, démarrer un enregistrement (en cochant Preserve log pour qu’elle ne disparaisse pas au changement de page) et faire les manipulations que l’on veut reproduire lors de nos tests de charge. Une fois terminé, on peut l’enregistrer sous format har.

creerHar

On lance ensuite le recorder et on lui injecte le fichier* .har précédemment créé.* Selon notre besoin on peut décider de ne pas prendre en compte les ressources statiques (mises alors dans la blacklist).

gatlingrecorder

Le scénario est généré dans gatling/user-files/simulation. Voici à quoi il ressemble :


import scala.concurrent.duration._

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.jdbc.Predef._

class RecordedSimulation extends Simulation {

	val httpProtocol = http
		.baseURL("http://computer-database.herokuapp.com")
		.inferHtmlResources(BlackList(""".*\.js""", """.*\.css""", """.*\.gif""", """.*\.jpeg""", """.*\.jpg""", """.*\.ico""", """.*\.woff""", """.*\.(t|o)tf""", """.*\.png"""), WhiteList())
		.acceptHeader("""text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8""")
		.acceptEncodingHeader("""gzip, deflate, sdch""")
		.acceptLanguageHeader("""fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4""")
		.connection("""keep-alive""")
		.userAgentHeader("""Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36""")

	val headers_0 = Map("""Cache-Control""" -> """max-age=0""")

    val uri1 = """http://computer-database.herokuapp.com/computers"""

	val scn = scenario("RecordedSimulation")
		.exec(http("request_0")
			.get("""/computers""")
			.headers(headers_0))
		.pause(5)
		.exec(http("request_1")
			.get("""/computers?f=test"""))
		.pause(3)
		.exec(http("request_2")
			.get("""/computers/378"""))
		.pause(4)
		.exec(http("request_3")
			.get("""/computers"""))

	setUp(scn.inject(atOnceUsers(1))).protocols(httpProtocol)
}

On remarque que, même sans rien connaître de Scala, ce code est facilement lisible. Rossi recommande l’utilisation de Scala IDE pour le manipuler. La suite de la démonstration s’est faite sur l’amélioration du code généré pour le rendre plus lisible et maintenable. Il est ainsi possible de séparer notre scénario en plusieurs processus. Voici alors à quoi pourrait ressembler le code :

object Recherche {

  val recherche = exec(http("Search")
			.get("""/computers?f=test"""))
		.pause(3)
}

object Selection {

  val selection = exec(http("Browse")
			.get("""/computers/378"""))
		.pause(4)
}

object Browse {

  val browse = exec(http("Home")
		.get("""/computers"""))
		.pause(5)

}

L’intérêt est de créer plus facilement différents enchaînements de scénarios, correspondant à plusieurs types de comportement, et donc des utilisateurs différents pour notre simulation. Imaginons que nous avons un scénario supplémentaire dans lequel l’utilisateur édite l’entrée sélectionnée. Nous pouvons alors écrire :

val users = scenario("Users").exec(Browse.browse, Recherche.recherche, Selection.selection, Browse.browse)
val admins = scenario("Admins").exec(Browse.browse, Recherche.recherche, Selection.selection, Edit.edit)

Et si nous voulons maintenant simuler l’arrivée progressive de 1000 utilisateurs et celle simultanée de 10 administrateurs, il nous reste à réécrire la dernière ligne :

setUp(
  users.inject(rampUsers(1000) over (10 seconds)),
  admins.inject(atOnceUsers(10))
).protocols(httpProtocol)

La suite de la démonstration s’est portée sur l’utilisation d’un feeder pour pouvoir varier les données passées à un formulaire, depuis un fichier de type csv ou une base de données.

Voila comment déclarer un feeder :

val feeder = csv("search.csv").queue

Ce feeder prendra les lignes dans l’ordre et s’arrêtera quand il arrivera à la fin, il faut donc veiller à avoir au moins autant de lignes que d’utilisateurs. Si on a moins de lignes que d’utilisateurs, on utilisera alors circular à la place de queue pour revenir au début du fichier. On peut également prendre les lignes aléatoirement avec random.

Enfin, il est possible d’ajouter des vérifications dans le scénario : statut de la réponse ou recherche d’une expression régulière dans la réponse.

Une fois notre scénario bien écrit, on peut le tester en lançant gatling. L’application nous demande alors de choisir quelle simulation on souhaite jouer, puis nous en voyons le déroulement dans la console. Un rapport très complet et lisible est généré sous format html.

gatlingrapport

Pour aller plus loin, le blog de Rossi Oddet contient plusieurs articles sur Gatling et Scala. Vous pouvez aussi consulter le tutoriel avancé de Gatling que j’ai outrageusement pompé pour compléter mes notes éparses de la session du JUG.

Crédit photo
https://flic.kr/p/72zZMX


Vous avez trouvé cette publication utile? Cliquer sur
Ippon
Ippon est un cabinet de conseil en technologies, créé en 2002 par un sportif de Haut Niveau et un polytechnicien, avec pour ambition de devenir leader sur les solutions Digitales, Cloud et BigData.

Ippon accompagne les entreprises dans le développement et la transformation de leur système d’information avec des applications performantes et des solutions robustes.

Ippon propose une offre de services à 360° pour répondre à l’ensemble des besoins en innovation technologique : Conseil, Design, Développement, Hébergement et Formation.

Nous avons réalisé, en 2016, un chiffre d’affaires de 24 M€ en croissance organique de 20%. Nous sommes aujourd’hui un groupe international riche de plus de 300 consultants répartis en France, aux USA, en Australie et au Maroc.
FRANCE Website LinkedIn