Gatling vs JMeter vs The Grinder: Vergleichen von Lasttest-Tools

1. Einleitung

Die Wahl des richtigen Werkzeugs für den Job kann entmutigend sein. In diesem Lernprogramm vereinfachen wir dies, indem wir drei Lasttest-Tools für Webanwendungen - Apache JMeter, Gatling und The Grinder - mit einer einfachen REST-API vergleichen.

2. Testtools laden

Lassen Sie uns zunächst einige Hintergrundinformationen zu den einzelnen Themen kurz überprüfen.

2.1. Gatling

Gatling ist ein Lasttest-Tool, das Testskripte in Scala erstellt. Der Rekorder von Gatling generiert die Scala-Testskripte, eine wichtige Funktion von Gatling. Weitere Informationen finden Sie in unserem Tutorial zur Einführung in Gatling.

2.2. JMeter

JMeter ist ein Lasttest-Tool von Apache. Es bietet eine schöne GUI, die wir für die Konfiguration verwenden können. Eine einzigartige Funktion namens Logik-Controller bietet große Flexibilität beim Einrichten von Tests in der GUI.

In unserem Tutorial zur Einführung in JMeter finden Sie Screenshots und weitere Erklärungen.

2.3. Der Schleifer

Und unser letztes Tool, The Grinder, bietet eine programmierbasiertere Scripting-Engine als die beiden anderen und verwendet Jython. Der Grinder 3 verfügt jedoch über Funktionen zum Aufzeichnen von Skripten.

Der Grinder unterscheidet sich auch von den beiden anderen Tools durch die Berücksichtigung von Konsolen- und Agentenprozessen. Diese Funktionalität bietet die Möglichkeit für einen Agentenprozess, sodass die Auslastungstests auf mehrere Server skaliert werden können. Es wird speziell als Lasttest-Tool beworben, mit dem Entwickler Deadlocks und Verlangsamungen finden können.

3. Testfall einrichten

Als nächstes benötigen wir für unseren Test eine API. Unsere API-Funktionalität umfasst:

  • Hinzufügen / Aktualisieren eines Belohnungsdatensatzes
  • einen / alle Belohnungsdatensätze anzeigen
  • Verknüpfen Sie eine Transaktion mit einem Kundenbelohnungsdatensatz
  • Anzeigen von Transaktionen für einen Kundenbelohnungsdatensatz

Unser Szenario:

Ein Geschäft hat einen landesweiten Verkauf mit neuen und wiederkehrenden Kunden, die Kundenprämienkonten benötigen, um Einsparungen zu erzielen. Die Belohnungs-API prüft anhand der Kunden-ID, ob ein Kundenbelohnungskonto vorhanden ist . Wenn kein Prämienkonto vorhanden ist, fügen Sie es hinzu und verknüpfen Sie es mit der Transaktion.

Danach fragen wir die Transaktionen ab.

3.1. Unsere REST-API

Lassen Sie uns einen kurzen Überblick über die API geben, indem wir einige der Methodenstubs anzeigen:

@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) 

Beachten Sie einige der Beziehungen, z. B. das Abfragen von Transaktionen anhand der Prämien-ID und das Abrufen des Prämienkontos anhand der Kunden-ID . Diese Beziehungen erzwingen eine gewisse Logik und eine gewisse Analyse der Antworten für die Erstellung unseres Testszenarios.

Die zu testende Anwendung verwendet für die Persistenz auch eine H2-In-Memory-Datenbank.

Glücklicherweise handhaben unsere Werkzeuge alle ziemlich gut, einige besser als andere.

3.2. Unser Testplan

Als nächstes benötigen wir Testskripte.

Um einen fairen Vergleich zu erhalten, führen wir für jedes Tool dieselben Automatisierungsschritte durch:

  1. Generieren Sie zufällige Kundenkonto-IDs
  2. Buchen Sie eine Transaktion
  3. Analysieren Sie die Antwort für die zufällige Kunden-ID und die Transaktions-ID
  4. Die Abfrage einer Kundenbelohnungs-Konto-ID mit der Kunden-ID
  5. Analysieren Sie die Antwort für die ID des Prämienkontos
  6. Wenn keine Prämienkonto-ID vorhanden ist, fügen Sie eine mit einem Beitrag hinzu
  7. Buchen Sie dieselbe erste Transaktion mit aktualisierter Belohnungs-ID unter Verwendung der Transaktions-ID
  8. Abfrage aller Transaktionen nach Prämienkonto-ID

Schauen wir uns Schritt 4 für jedes Werkzeug genauer an. Überprüfen Sie auch das Beispiel für alle drei abgeschlossenen Skripte.

3.3. Gatling

Für Gatling ist die Vertrautheit mit Scala ein Segen für Entwickler, da die Gatling-API robust ist und viele Funktionen enthält.

Die API von Gatling verfolgt einen Builder-DSL-Ansatz, wie wir in Schritt 4 sehen können:

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

Besonders hervorzuheben ist die Unterstützung von Gatling für JSON Path, wenn eine HTTP-Antwort gelesen und überprüft werden muss. Hier holen wir uns die Belohnungs-ID und speichern sie im internen Status von Gatling.

Die Ausdruckssprache von Gatling erleichtert außerdem den dynamischen Anforderungskörper. Zeichenfolgen:

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

Zuletzt unsere Konfiguration für diesen Vergleich. Die 1000 Läufe werden als Wiederholung des gesamten Szenarios festgelegt. Die Methode atOnceUsers legt die Threads / Benutzer fest:

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

Das gesamte Scala-Skript kann in unserem Github-Repo eingesehen werden.

3.4. JMeter

JMeter generiert nach der GUI-Konfiguration eine XML-Datei. Die Datei enthält JMeter-spezifische Objekte mit festgelegten Eigenschaften und deren Werten, zum Beispiel:

Überprüfen Sie die Testnamenattribute . Sie können beschriftet werden, wenn wir erkennen, dass sie mit den obigen logischen Schritten übereinstimmen. Die Möglichkeit, untergeordnete Elemente, Variablen und Abhängigkeitsschritte hinzuzufügen, bietet JMeter Flexibilität wie bei der Skripterstellung. Darüber hinaus legen wir sogar den Umfang für unsere Variablen fest!

Unsere Konfiguration für Läufe und Benutzer in JMeter verwendet 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
  • Apache Foundation Support und großartige Integration mit Maven

Der Schleifer:

  • Schnelles Tool zum Testen der Leistungslast für Entwickler, die Jython verwenden
  • Die serverübergreifende Skalierbarkeit bietet noch mehr Potenzial für große Tests

Einfach ausgedrückt, wenn Geschwindigkeit und Skalierbarkeit erforderlich sind, verwenden Sie The Grinder.

Wenn gut aussehende interaktive Diagramme einen Leistungsgewinn anzeigen, um für eine Änderung zu argumentieren, verwenden Sie Gatling.

JMeter ist das Tool für komplizierte Geschäftslogik oder eine Integrationsschicht mit vielen Nachrichtentypen. Als Teil der Apache Software Foundation bietet JMeter ein ausgereiftes Produkt und eine große Community.

6. Fazit

Zusammenfassend sehen wir, dass die Werkzeuge in einigen Bereichen vergleichbare Funktionen haben, während sie in anderen glänzen. Das richtige Werkzeug für den richtigen Job ist umgangssprachliche Weisheit, die in der Softwareentwicklung funktioniert.

Schließlich finden Sie die API und die Skripte auf Github.