Gatling vs JMeter vs The Grinder: Sammenligning af belastningstestværktøjer

1. Introduktion

At vælge det rigtige værktøj til jobbet kan være skræmmende. I denne vejledning forenkler vi dette ved at sammenligne tre værktøjer til belastningstestning af webapplikationer - Apache JMeter, Gatling og The Grinder - med en simpel REST API.

2. Indlæs testværktøjer

Lad os først gennemgå lidt baggrund for hver.

2.1. Gatling

Gatling er et belastningstestværktøj, der opretter testscripts i Scala. Gatlings optager genererer Scala test-scripts, en nøglefunktion for Gatling. Se vores introduktion til Gatling-vejledning for at få flere oplysninger.

2.2. JMeter

JMeter er et belastningstestværktøj fra Apache. Det giver en god GUI, som vi bruger kan til konfiguration. En unik funktion kaldet logiske controllere giver stor fleksibilitet til at oprette tests i GUI.

Besøg vores Intro til JMeter-vejledning for skærmbilleder og mere forklaring.

2.3. Kværnen

Og vores sidste værktøj, The Grinder, giver en mere programmeringsbaseret scriptmotor end de to andre og bruger Jython. The Grinder 3 har dog funktionalitet til optagelse af scripts.

Grinder adskiller sig også fra de to andre værktøjer ved at tillade konsol- og agentprocesser. Denne funktionalitet giver mulighed for en agentproces, så belastningstestene kan skaleres op på flere servere. Det er specifikt annonceret som et belastningstestværktøj bygget til udviklere til at finde blokeringer og afmatninger.

3. Test sagsopsætning

Dernæst har vi brug for en API til vores test. Vores API-funktionalitet inkluderer:

  • tilføj / opdater en belønningspost
  • se en / alle belønningsposter
  • knytte en transaktion til en kundebelønningspost
  • se transaktioner for en kunde belønningspost

Vores scenarie:

En butik har et landsdækkende salg med nye og tilbagevendende kunder, der har brug for kundebelønningskonti for at få besparelser. Belønnings-API'et kontrollerer for kundebelønningskonto efter kunde-id'et. Hvis der ikke findes en belønningskonto, skal du tilføje den og derefter linke til transaktionen.

Herefter forespørger vi transaktionerne.

3.1. Vores REST API

Lad os få en hurtig fremhævning af API'en ved at se nogle af metodestubberne:

@PostMapping (sti = "/ belønninger / tilføj") offentlig @ResponseBody RewardsAccount addRewardsAcount (@RequestBody RewardsAccount body) @GetMapping (path = "/ rewards / find / {customerId}") public @ResponseBody Valgfri findCustomer (@PathVariable Integer customerId) @PostMapping (sti = "/ transaktioner / tilføj") offentlig @ResponseBody Transaktion addTransaction (@RequestBody Transaktionstransaktion) @GetMapping (sti = "/ transaktioner / findAll / {rewardId}") offentlig @ResponseBody Iterabel findTransactions (@PathVariable Integer rewardId) 

Bemærk nogle af forholdene, såsom forespørgsel efter transaktioner efter belønnings-id og få belønningskontoen efter kunde-id. Disse forhold tvinger nogle logik og nogle svar parsing for vores test scenarie oprettelse.

Den anvendte applikation bruger også en H2-hukommelsesdatabase til vedholdenhed.

Heldigvis håndterer vores værktøjer det ret godt, nogle bedre end andre.

3.2. Vores testplan

Dernæst har vi brug for testskripter.

For at få en rimelig sammenligning udfører vi de samme automatiseringstrin for hvert værktøj:

  1. Generer tilfældige kundekonto-id'er
  2. Bogfør en transaktion
  3. Parse svaret for det tilfældige kunde-id og transaktions-id
  4. Forespørgsel efter en kunde belønner konto-id med kunde-id
  5. Parse svaret til belønningskonto-id'et
  6. Hvis der ikke findes nogen belønningskonto-id, skal du tilføje en med et indlæg
  7. Bogfør den samme oprindelige transaktion med opdateret belønnings-id ved hjælp af transaktions-id
  8. Forespørgsel om alle transaktioner efter belønningskonto-id

Lad os se nærmere på trin 4 for hvert værktøj. Og sørg for at tjekke prøven for alle tre færdige scripts.

3.3. Gatling

For Gatling tilføjer fortrolighed med Scala en velsignelse for udviklere, da Gatling API er robust og indeholder mange funktioner.

Gatlings API tager en builder DSL-tilgang, som vi kan se i trin 4:

.exec (http ("get_reward") .get ("/ rewards / find / $ {custId}") .check (jsonPath ("$. id"). saveAs ("rwdId"))) 

Navnlig er Gatlings support til JSON Path, når vi har brug for at læse og verificere et HTTP-svar. Her henter vi belønnings-id'et og gemmer det i Gatlings interne tilstand.

Gatlings ekspressionssprog giver også lettere dynamisk anmodningskrop Strenge:

.body (StringBody ("" "{" customerRewardsId ":" $ {rwdId} "," customerId ":" $ {custId} "," transactionDate ":" $ {txtDate} "}" "")). asJson) 

Endelig vores konfiguration til denne sammenligning. De 1000 kørsler indstillet som en gentagelse af hele scenariet, hosOnceUsers metode indstiller tråde / brugere:

val scn = scenario ("RewardsScenario"). gentag (1000) {...} setUp (scn.inject (atOnceUsers (100))). protokol (httpProtocol)

Hele Scala-scriptet kan ses på vores Github-repo.

3.4. JMeter

JMeter genererer en XML-fil efter GUI-konfigurationen. Filen indeholder JMeter-specifikke objekter med indstillede egenskaber og deres værdier, for eksempel:

Tjek testnavn attributter, kan de mærkes, når vi genkender dem, der matcher de logiske trin ovenfor. Evnen til at tilføje børn, variabler og afhængighedstrin giver JMeter fleksibilitet som scripting giver. Desuden indstiller vi endda omfanget for vores variabler!

Vores konfiguration til kørsler og brugere i JMeter-anvendelser Trådgrupper:

100

Se det hele jmx fil som reference. Mens det er muligt, skriver du test i XML som .jmx filer giver ikke mening med en komplet GUI.

3.5. Kværnen

Uden den funktionelle programmering af Scala og GUI ser vores Jython-script til The Grinder ret grundlæggende ud. Tilføj nogle system Java-klasser, og vi har meget færre linjer med kode.

customerId = str (random.nextInt ()); resultat = anmodning1.POST ("// localhost: 8080 / transaktioner / tilføj", "{" '"customerRewardsId"' ": null," '"customerId"' ":" + customerId + "," '"transactionDate"' ": null}") txnId = parseJsonString (result.getText (), "id")

Imidlertid afbalanceres færre linjer med testopsætningskode ved behovet for mere strengvedligeholdelseskode, såsom parsing af JSON-strenge. HTTPRequest API er også slank på funktionalitet.

Med The Grinder definerer vi tråde, processer og kører værdier i en ekstern egenskabsfil:

grinder.threads = 100 grinder.processes = 1 grinder.runs = 1000

Vores fulde Jython-script til The Grinder vil se sådan ud.

4. Testkørsler

4.1. Testudførelse

Alle tre værktøjer anbefaler at bruge kommandolinjen til store belastningstest.

For at køre testene bruger vi Gatling open-source version 3.4.0 som et enkeltstående værktøj, JMeter 5.3 og The Grinder version 3.

Gatling kræver kun, at vi har JAVA_HOME og GATLING_HOME sæt. For at udføre Gatling bruger vi:

./gatling.sh

i GATLING_HOME / bin-biblioteket.

JMeter har brug for en parameter for at deaktivere GUI til testen som bedt om, når GUI startes til konfiguration:

./jmeter.sh -n -t TestPlan.jmx -l log.jtl

Ligesom Gatling kræver The Grinder, at vi indstiller JAVA_HOME og GRINDERPATH. Det har dog også brug for et par flere egenskaber:

eksport CLASSPATH = / home / lore / Documents / grinder-3 / lib / grinder.jar: $ CLASSPATH eksport GRINDERPROPERTIES = / home / lore / Documents / grinder-3 / examples / grinder.properties

Som nævnt ovenfor leverer vi en kværn. ejendomme fil til yderligere konfiguration såsom tråde, kørsler, processer og konsolværter.

Endelig bootstrap vi konsollen og agenterne med:

java -classpath $ CLASSPATH net.grinder.Console
java -classpath $ CLASSPATH net.grinder.Grinder $ GRINDERPROPERTIES

4.2. Test resultater

Hver af testene kørte 1000 kørsler med 100 brugere / tråde. Lad os pakke nogle af højdepunkterne ud:

Vellykkede anmodningerFejlTotal testtid (er)Gennemsnitlig svartid (ms) Gennemsnitlig gennemstrømning
Gatling500000 anmodninger0218s422283 krav / s
JMeter499997 Anmodninger0237s462101 req / s
Kværnen499997 Anmodninger0221s432280 krav / sek

Resultaterne viser, at de 3 værktøjer har samme hastighed, hvor Gatling let kanter de andre 2 ud, baseret på den gennemsnitlige kapacitet.

Hvert værktøj giver også yderligere oplysninger i en mere brugervenlig brugergrænseflade.

Gatling genererer en HTML-rapport i slutningen af ​​løbet, som indeholder flere grafer og statistikker, for den samlede kørsel såvel som for hver anmodning. Her er et uddrag af testresultatrapporten:

Når du bruger JMeter, kan vi åbne GUI'en efter testkørslen og generere en HTML-rapport baseret på logfilen hvor vi gemte resultaterne:

JMeter HTML-rapporten indeholder også en oversigt over statistikkerne pr. Anmodning.

Endelig registrerer Grinder Console statistik for hver agent og kører:

Mens Grinder er højhastighedstog, koster det ekstra udviklingstid og mindre mangfoldighed af outputdata.

5. Resume

Nu er det tid til at tage et samlet kig på hvert af belastningstestværktøjerne.

GatlingJMeterKværnen
Projekt og fællesskab996
Ydeevne989
Skriptbarhed / API798
UI986
Rapporter976
Integration797
Resumé8.38.37

Gatling:

  • Solid, poleret belastningstestværktøj, der udsender smukke rapporter med Scala-scripting
  • Open source og Enterprise supportniveauer for produktet

JMeter:

  • Robust API (via GUI) til test script-udvikling uden kodning krævet
  • Apache Foundation Support og god integration med Maven

Kværnen:

  • Hurtigt præstationsværktøjsværktøj til udviklere, der bruger Jython
  • Skalerbarhed på tværs af servere giver endnu større potentiale for store tests

Kort sagt, hvis hastighed og skalerbarhed er et behov, så brug The Grinder.

Hvis flotte interaktive grafer hjælper med at vise en præstationsgevinst for at argumentere for en ændring, skal du bruge Gatling.

JMeter er værktøjet til kompliceret forretningslogik eller et integrationslag med mange meddelelsestyper. Som en del af Apache Software Foundation leverer JMeter et modent produkt og et stort samfund.

6. Konklusion

Afslutningsvis ser vi, at værktøjerne har sammenlignelige funktioner i nogle områder, mens de skinner i andre. Det rigtige værktøj til det rigtige job er dagligdags visdom, der fungerer inden for softwareudvikling.

Endelig kan API og scripts findes på Github.


$config[zx-auto] not found$config[zx-overlay] not found