Gatling vs JMeter vs The Grinder: confronto tra strumenti di test di carico

1. Introduzione

Scegliere lo strumento giusto per il lavoro può essere scoraggiante. In questo tutorial, lo semplificheremo confrontando tre strumenti di test del carico di applicazioni web - Apache JMeter, Gatling e The Grinder - con una semplice API REST.

2. Strumenti per il test di carico

Per prima cosa, esaminiamo rapidamente alcuni retroscena su ciascuno.

2.1. Gatling

Gatling è uno strumento di test del carico che crea script di test in Scala. Il registratore di Gatling genera gli script di prova Scala, una caratteristica fondamentale per Gatling. Dai un'occhiata al nostro tutorial Intro to Gatling per maggiori informazioni.

2.2. JMeter

JMeter è uno strumento di test del carico di Apache. Fornisce una bella GUI che usiamo per la configurazione. Una caratteristica unica chiamata controller logici offre una grande flessibilità per impostare i test nella GUI.

Visita il nostro tutorial Intro to JMeter per screenshot e ulteriori spiegazioni.

2.3. Il macinino

E il nostro strumento finale, The Grinder, fornisce un motore di scripting più basato sulla programmazione rispetto agli altri due e utilizza Jython. Tuttavia, The Grinder 3 ha funzionalità per la registrazione di script.

Il Grinder si differenzia anche dagli altri due strumenti consentendo processi di console e agente. Questa funzionalità fornisce la possibilità per un processo agente in modo che i test di carico possano essere scalati su più server. È specificamente pubblicizzato come uno strumento di test del carico creato per gli sviluppatori per trovare deadlock e rallentamenti.

3. Configurazione dello scenario di test

Successivamente, per il nostro test, abbiamo bisogno di un'API. La nostra funzionalità API include:

  • aggiungere / aggiornare un record di ricompense
  • visualizzare uno / tutti i record dei premi
  • collegare una transazione a un record dei premi del cliente
  • visualizzare le transazioni per un record di premi del cliente

Il nostro scenario:

Un negozio sta effettuando una vendita a livello nazionale con clienti nuovi e di ritorno che necessitano di account di premi cliente per ottenere risparmi. L'API dei premi controlla l'account dei premi del cliente in base all'ID cliente . Se non esiste alcun conto premi, aggiungilo, quindi collegalo alla transazione.

Successivamente, interroghiamo le transazioni.

3.1. La nostra API REST

Vediamo una rapida panoramica dell'API visualizzando alcuni degli stub del metodo:

@PostMapping(path="/rewards/add") public @ResponseBody RewardsAccount addRewardsAcount(@RequestBody RewardsAccount body) @GetMapping(path="/rewards/find/{customerId}") public @ResponseBody Optional findCustomer(@PathVariable Integer customerId) @PostMapping(path="/transactions/add") public @ResponseBody Transaction addTransaction(@RequestBody Transaction transaction) @GetMapping(path="/transactions/findAll/{rewardId}") public @ResponseBody Iterable findTransactions(@PathVariable Integer rewardId) 

Nota alcune delle relazioni come la ricerca delle transazioni tramite l'ID ricompensa e l'ottenimento dell'account premi tramite l'ID cliente . Queste relazioni impongono una logica e un'analisi delle risposte per la creazione dello scenario di test.

L'applicazione sottoposta a test utilizza anche un database in memoria H2 per la persistenza.

Fortunatamente, i nostri strumenti lo gestiscono tutti abbastanza bene, alcuni meglio di altri.

3.2. Il nostro piano di test

Successivamente, abbiamo bisogno di script di test.

Per ottenere un confronto equo, eseguiremo gli stessi passaggi di automazione per ogni strumento:

  1. Genera ID account cliente casuali
  2. Pubblica una transazione
  3. Analizza la risposta per l'ID cliente casuale e l'ID transazione
  4. Richiesta di un ID account cliente premi con l'ID cliente
  5. Analizza la risposta per l'ID account premi
  6. Se non esiste alcun ID account premi, aggiungine uno con un post
  7. Pubblica la stessa transazione iniziale con l'ID dei premi aggiornato utilizzando l'ID della transazione
  8. Interroga tutte le transazioni in base all'ID account premi

Diamo uno sguardo più da vicino al passaggio 4 per ogni strumento. Inoltre, assicurati di controllare l'esempio per tutti e tre gli script completati.

3.3. Gatling

Per Gatling, la familiarità con Scala aggiunge un vantaggio per gli sviluppatori poiché l'API Gatling è robusta e contiene molte funzionalità.

L'API di Gatling adotta un approccio DSL di builder, come possiamo vedere nel suo passaggio 4:

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

Di particolare rilievo è il supporto di Gatling per JSON Path quando è necessario leggere e verificare una risposta HTTP. Qui, prenderemo l'ID della ricompensa e lo salveremo nello stato interno di Gatling.

Inoltre, il linguaggio di espressione di Gatling semplifica le stringhe dinamiche del corpo della richiesta :

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

Infine la nostra configurazione per questo confronto. Le 1000 corse impostate come ripetizione dell'intero scenario, il metodo atOnceUsers imposta i thread / utenti:

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

L'intero script Scala è visualizzabile nel nostro repository Github.

3.4. JMeter

JMeter genera un file XML dopo la configurazione della GUI. Il file contiene oggetti specifici di JMeter con proprietà impostate e relativi valori, ad esempio:

Controlla gli attributi testname , possono essere etichettati come li riconosciamo che corrispondono ai passaggi logici sopra. La possibilità di aggiungere figli, variabili e passaggi di dipendenza conferisce a JMeter la flessibilità fornita dallo script. Inoltre, abbiamo persino stabilito l'ambito per le nostre variabili!

La nostra configurazione per le esecuzioni e gli utenti in JMeter utilizza ThreadGroups :

100

View the entire jmx file as a reference. While possible, writing tests in XML as .jmx files do not make sense with a full-featured GUI.

3.5. The Grinder

Without the functional programming of Scala and GUI, our Jython script for The Grinder looks pretty basic. Add some system Java classes, and we have a lot fewer lines of code.

customerId = str(random.nextInt()); result = request1.POST("//localhost:8080/transactions/add", "{"'"customerRewardsId"'":null,"'"customerId"'":"+ customerId + ","'"transactionDate"'":null}") txnId = parseJsonString(result.getText(), "id")

However, fewer lines of test setup code are balanced by the need for more string maintenance code such as parsing JSON strings. Also, the HTTPRequest API is slim on functionality.

With The Grinder, we define threads, processes, and runs values in an external properties file:

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

Our full Jython script for The Grinder will look like this.

4. Test Runs

4.1. Test Execution

All three tools recommend using the command line for large load tests.

To run the tests, we'll use Gatling open-source version 3.4.0 as a standalone tool, JMeter 5.3 and The Grinder version 3.

Gatling requires only that we have JAVA_HOME and GATLING_HOME set. To execute Gatling we use:

./gatling.sh

in the GATLING_HOME/bin directory.

JMeter needs a parameter to disable the GUI for the test as prompted when starting the GUI for configuration:

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

Like Gatling, The Grinder requires that we set JAVA_HOME and GRINDERPATH. However, it needs a couple more properties, too:

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

As mentioned above, we provide a grinder.properties file for additional configuration such as threads, runs, processes, and console hosts.

Finally, we bootstrap the console and agents with:

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

4.2. Test Results

Each of the tests ran 1000 runs with 100 users/threads. Let's unpack some of the highlights:

Successful Requests Errors Total Test Time (s) Average Response Time (ms) Mean Throughput
Gatling 500000 Requests 0 218s 42 2283 req/s
JMeter 499997 Requests 0 237s 46 2101 req/s
The Grinder 499997 Requests 0 221s 43 2280 req/s

The results show the 3 tools have similar speed, with Gatling slightly edging out the other 2, based on the mean throughput.

Each tool also provides additional information in a friendlier user interface.

Gatling will generate an HTML report at the end of the run, which contains multiple graphs and statistics, for the total run as well as for each request. Here's a snippet of the test result report:

When using JMeter, we can open the GUI after the test run and generate an HTML report based on the log file where we saved the results:

The JMeter HTML report also contains a breakdown of the statistics per request.

Finally, The Grinder Console records statistics for each agent and run:

While The Grinder is high-speed, it comes at the cost of additional development time and less diversity of output data.

5. Summary

Now it's time to take an overall look at each of the load testing tools.

Gatling JMeter The Grinder
Project and Community 9 9 6
Performance 9 8 9
Scriptability/API 7 9 8
UI 9 8 6
Reports 9 7 6
Integration 7 9 7
Summary 8.3 8.3 7

Gatling:

  • Solid, polished load testing tool that outputs beautiful reports with Scala scripting
  • Open Source and Enterprise support levels for the product

JMeter:

  • Robust API (through GUI) for test script development with no coding required
  • Supporto per Apache Foundation e ottima integrazione con Maven

Il macinino:

  • Strumento di test del carico rapido delle prestazioni per gli sviluppatori che utilizzano Jython
  • La scalabilità tra server offre un potenziale ancora maggiore per test di grandi dimensioni

In poche parole, se velocità e scalabilità sono necessarie, usa The Grinder.

Se grafici interattivi dall'aspetto accattivante aiutano a mostrare un miglioramento delle prestazioni per sostenere un cambiamento, allora usa Gatling.

JMeter è lo strumento per la logica aziendale complicata o un livello di integrazione con molti tipi di messaggi. Come parte della Apache Software Foundation, JMeter fornisce un prodotto maturo e una vasta comunità.

6. Conclusione

In conclusione, vediamo che gli strumenti hanno funzionalità comparabili in alcune aree mentre brillano in altre. Lo strumento giusto per il lavoro giusto è la saggezza colloquiale che funziona nello sviluppo del software.

Infine, l'API e gli script possono essere trovati su Github.