Last- und Performance-Tests mit JMeter oder Gatling

Die Performance wird bei Anwendungen zunehmend zur kritischen Anforderung. Je früher Performanceengpässe erkannt und Grenzen bekannt sind, desto so einfacher lässt sich darauf reagieren. Im Folgenden vergleicht heise Developer zwei beliebte Lasttestwerkzeuge – den Platzhirsch JMeter und seinen Herausforderer Gatling.

Werkzeuge  –  1 Kommentare

Die Anfänge von Apache JMeter reichen noch ins letzte Jahrtausend, als das Web und der Java-Webserver Apache Tomcat noch in den Kinderschuhen steckten, für den JMeter ursprünglich entwickelt wurde. Das Alter sieht man JMeter mit seiner Swing-basierten Oberfläche an. Ansonsten hat das Tool über die Jahrzehnte eine kontinuierliche Weiterentwicklung erfahren und seine Reife in vielen Einsätzen bewiesen. Letztlich dient die Oberfläche nur dazu, die XML-basierten Testpläne zu erstellen und testweise auszuführen. Meist wird JMeter jedoch nicht über die Oberfläche, sondern auf der Kommandozeile mit dem folgenden Aufruf gestartet:

jmeter -n -t <testplan JMX file> -l <testlog file> -e -o
<Path to resultsoutput folder>
Einfacher JMeter-Testplan (Abb. 1)

Um die Heise-Webseite zu testen, brauchen Entwickler mindestens eine Thread-Gruppe und einen HTTP Requester. Umfangreichere Testpläne lassen sich für HTTP auch mit einem Testrecorder erstellen. Wenn man hier vorher die Variablen mit Werten angelegt hat, lassen sich die Werte beim Aufnehmen durch entsprechende Variablen ersetzen. Damit der Testrecorder Anfragen und Antworten mitschreibt, wird JMeter als Proxy zwischen Browser und aufgerufenen Server gestellt. Alternativ kann man die HTTP-Anfragen und -Antworten durch entsprechende Browsererweiterungen im HAR-Format (HTTP Archive) speichern. Das HAR-Archiv lässt sich dann mit Werkzeugen, zum Beispiel online mit dem ".har to .jmx converter", in das JMX-Format eines JMeter-Testplans umwandeln.

Bei großen verteilten Tests kommt eine Master-Slave-Konfiguration zum Einsatz, bei der die Slaves (jmeter-server.[bat|sh]) vorher gestartet werden und mit dem Master (jmeter.bat Remote Start All remote_hosts) über den RMI-Port 1099 (Remote Method Invocation) kommunizieren. Der Master steuert nicht nur die Testausführung und die Verteilung des Testplans, sondern sammelt auch die Ergebnisse ein. Da jedoch viele Firewalls das RMI-Protokoll blockieren, nehmen oft eigene, über SSH angesprochene Skripte das Ausführen und Steuern vor. Hierfür gibt es im Web einige Cloud-Angebote, etwa von BlazeMeter, das letztes Jahr von CA übernommen wurde. Oder man verwendet die Cloud-Dienste von AWS wie EC2, um selbst ein JMeter-Testszenario aufzubauen. Die Cloud hat für Performancetests den Vorteil, dass Ressourcen flexibel und kostengünstig auf Bedarf zur Verfügung stehen. Ein fertiger Satz von JMeter-EC2-Skripten findet sich beispielsweise auf Oliver Lloyds GitHub-Seite.

Bessere Berichte und viele Protokolle

Neben der altbackenen Oberfläche und der begrenzten Multithreading-Fähigkeit gab es an JMeter vor allem Kritik an eingeschränkten Berichtsmöglichkeiten. Doch seit der 3er-Version, die sich leider drei Jahre Zeit gelassen hat, gibt es interaktive HTML-Berichte mit erweiterten Metriken wie Apdex (Application Performance Index). Es stehen nach wie vor Möglichkeiten zur Verfügung, entweder kostenlos die Testergebnisse von BlazeMeter Sense als aussagekräftigen fertigen Online-Report erstellen zu lassen oder die Tests kostenpflichtig auf deren Infrastruktur von BlazeMeter auszuführen. Als Bonus kann man den Testbericht auch als PDF-Bericht herunterladen, um ihn zu versionieren oder an anderer Stelle zu verwenden.

Eine weitere Option, die Fähigkeiten von JMeter zu erweitern, sind Plug-ins. Hier bringt JMeter eine stetig wachsende Zahl eigener Erweiterungen mit. Es besteht zusätzlich die Option, eine Vielzahl spezialisierter Plug-ins herunterzuladen oder über den Plug-in-Manager einfach zu aktualisieren. Die damit erstellten Download-Statistiken zeigen, dass neuere JMeter-Versionen nach nur wenigen Wochen eingesetzt werden.

Verwendete JMeter-Versionen (Abb. 2)

Auch Testpläne, die mit älteren JMeter-Versionen erstellt wurden, sind ohne Probleme mit neueren Versionen einsetzbar, was den Umstieg erleichtert. Testpläne sollten unbedingt parametrisiert erstellt werden, damit sie in den Testumgebungen einfach zu nutzen sind. Um die Tests an spezielle Anforderungen anzupassen, gibt es die Möglichkeit, über Pre- und Post-Prozessoren das Verhalten zu beeinflussen. Hier ist besonders der JSON Path oder der Regular Expression PostProcessor hilfreich, um zusammen mit einfachen Groovy- oder JavaScript-Schnipseln als JSR 223 (Scripting for the Java Platform) Processor, Sampler, Assertion oder Listener das Verhalten der Tests zu beeinflussen. Dass sich JSR-223-Skripte vorkompilieren lassen, beschleunigt deren spätere Ausführung.

JMeter ist durch die breite Protokollunterstützung bekannt. So ist das Werkzeug nicht nur auf die typischen Webprotokolle (HTTP, FTP, SOAP, SMTP, POP3, IMAP, OAuth) beschränkt, sondern kann auch Java-EE-Standardprotokolle (JDBC, LDAP, JMS) verwenden, um die gesamte Systeminfrastruktur zu testen.

JMeter hat sich über die letzten Jahrzehnte zu einer verlässlichen Größe im Bereich Last- und Performancetests entwickelt. Dabei ist die Technik nicht stehen geblieben. Außerdem gibt es eine Vielzahl von Büchern, Informationen und Erweiterungen dazu, die kaum Wünsche offenlassen.

Gatling

Der Herausforderer

Gatling entstand vor rund sechs Jahren als Testwerkzeug für Webanwendungen mit einer eigenen Domain-Specific Language (DSL) für Testszenarien. Die technische Basis dafür sind die Programmiersprache Scala, die Aktoren-Implementierung Akka und die NIO-Client-Bibliothek Netty. Dadurch arbeitet Gatling asynchron und nichtblockierend. Als Ablaufumgebung benötigt Gatling ein JDK 8. Wegen der Verwendung von Scala ist Gatling eher etwas für Programmierer als für reine Testingenieure.

Mit dem Recorder können sie, ähnlich wie bei JMeter, die Interaktion zwischen Browser und Server über einen Proxy mitschreiben. Alternativ kann man auch mit einem anderen Werkzeug erstelltes HAR-Archiv (HTTP Archive) importieren und daraus Testszenariencode generieren. Gatling erstellt daraus eine Testklasse in Scala. Diese können Entwickler dann an ihre Bedürfnisse anpassen. Ein guter Einstieg zum Lernen sind fertige Testklassen für unterschiedliche Testszenarien. Sie kann man schnell, auch ohne tiefe Kenntnisse in Scala an seine Bedürfnisse anpassen.

Gatling-Testrecorder (Abb. 3)

Der erste Aufruf von Gatling dauert etwas, da der mitgelieferte Scala-Beispielcode noch in Java-Klassen zu übersetzen ist. Die fünf Beispiele liegen im Verzeichnis user-files\simulations\computerdatabase und werden zur Auswahl angeboten, wenn man Gatling ohne Parameter startet. Wer einen einzelnen Test starten möchte, gibt die Simulationsklasse an – zum Beispiel:

gatling.bat -s computerdatabase.advanced.AdvancedSimulationStep01

Der Testbericht im HTML-Format wird dann, wenn nicht anders spezifiziert, ins Verzeichnis results abgelegt. Den interaktiven Bericht ruft man durch das Öffnen der index.html-Datei auf.

Das Prinzip ist einfach: Entwickler erstellen eine Klasse, die von der Basisklasse Simulation erbt (class BasicSimulation extends Simulation) und setzen einzelne HTTP-Requests an die Basis-URL ab, die einem Testszenario zugeordnet sind. Zum Szenario lässt sich noch angeben, wie viel parallele Benutzer-Threads verwendet werden oder ob es eine initiale Warmlaufzeit gibt. Sollte man hinter einem Proxy sitzen, ist das der Basis-URL durch .proxy(Proxy("myProxyHost", 8080) mitzuteilen.

Um das Szenario in verschiedenen Umgebungen einsetzen zu können und die Anpassbarkeit zu erhöhen, sollten Entwickler die Werte der Parametervariablen außerhalb des Skripts pflegen. Zum Beispiel können Variablen für die Parameter aus einer CSV-Datei ausgelesen (val csvFeeder = csv("foo.csv")) werden. Ein einfacher Test der Heise-Seite sieht dann wie folgt aus:

class MySimulation extends Simulation {
val httpProtocol = http
.baseURL("https://www.heise.de/")
.inferHtmlResources()
val scn = scenario("Gatling")
.exec(http("request_0")
.get("/")
.check(status.is(200)))
setUp(scn.inject(atOnceUsers(1))).protocols(httpProtocol)
}

Die Oberfläche und die dynamischen Berichte hinterlassen einen modernen Eindruck.

Gatling-Testbericht (Abb. 4)

Zum Einstieg ist es sicherlich einfacher, entweder einen der mitgelieferten Berichte an die eigenen Bedürfnisse anzupassen oder sich einen mit dem mitgelieferten Test-Recorder erstellen zu lassen. Ein Vorteil von Gatling ist die gute Integrier- und Anpassbarkeit. Dafür gibt es nur wenige zusätzliche Erweiterungen oder tiefergehende Dokumentationen. Gatling hat den Schwerpunkt auf Webtests (HTTP, WebSockets, SSE), wenn auch wenige andere Protokolle (JMS) unterstützt werden. Weitere Nachteile sind, dass nur HTML-Berichte angeboten werden und Programmierkenntnisse in Scala nötig sind. Zwischen den Major-Versionen von Gatling kam es in der Vergangenheit, nicht nur durch Scala, immer wieder zu Änderungen, sodass ältere Tests entweder anzupassen oder neu zu erstellen sind.

Fazit

Beide Werkzeuge sind für umfangreiche Last- und Performancetest gut geeignet. Sie simulieren jedoch keinen vollwertigen Browser, sondern nur einfache HTTP-Clients. Da bisher nur ältere Versionen der Clients verwendet werden, wird erst mit Netty 4.1 (Gatling) und Apache HttpCore 5 (JMeter) eine HTTP/2-Unterstützung möglich sein.

Je mehr die Geschwindigkeit von Anwendungen jedoch von JavaScript abhängt, kann man zwar für diese Art der Anwendungen die Werkzeuge immer noch verwenden, indem man die aufgezeichneten Requests ausführt. Zusätzlich sollten die Tests jedoch um Funktionstests mit Selenium-Treibern für die relevanten Browser durchgeführt werden, um die für den Benutzer relevante und gefühlte Performance ebenso zu berücksichtigen.

Da die typischen Lasttestszenarien sowohl mit JMeter als auch Gatling gut durchgeführt werden können, gibt es keinen Sieger. Durch den DSL-basierten Ansatz und die moderne Berichtsausgabe ist Gatling sicherlich bei Entwicklern beliebt. JMeter kann jedoch mit der breiten Unterstützung verschiedener Lasttestszenarien und Erweiterungen punkten. Mit der 3er-Version hat JMeter bei den Scripting- und Reporting-Möglichkeiten aufgeholt. Bei den unterstützten Kommunikationsprotokollen und der Anzahl der verfügbaren Erweiterungen hat das Werkzeug klar die Nase vorn.

Letztlich hängt eine Entscheidung zugunsten des einen Werkzeugs oft von den Skills ab. Da Scala bei Gatling die Hauptsprache für Testpläne ist, sind hier eher Java- oder Scala-Programmierer angesprochen. Bei JMeter kann jedoch auch ein Testingenieur, nach einer kurzen Einarbeitungszeit, einfache Anpassungen und die Konfiguration des Testplans vornehmen. Da das Scripting in mehreren Programmiersprachen möglich ist, kommen auch Webprogrammierer aus dem Nicht-Java-Bereich gut mit JMeter klar.

Für die, die sich nicht entscheiden möchten oder können, bietet die Firma BlazeMeter das kostenlose Werkzeug Taurus an. Damit lassen sich die Stärken beider Werkzeuge unter einen Hut bringen, da so beide zusammen einsetzbar sind. (ane)

Frank Pientka
ist Principal Software Architect bei der Materna GmbH in Dortmund.