Wenn eine Site unter den vielen Interessenten ächzt, der Webshop unter dem Käuferansturm zusammenbricht oder bei einer Datenbank nur noch die Festplatten-LEDs Lebenszeichen geben, geraten Admins und Entwickler unter Stress. Ach, hätten sie die Applikation bloß in einer ruhigen Stunde unter Last gesetzt!
Um böse Überraschungen bei der Produktion zu vermeiden, ist es gute Praxis, seine Anwendung einem ausführlichen Lasttest zu unterziehen. Nur so können der Entwickler der Applikation und der zuständige Webmaster oder Admin verlässlich feststellen, welche Leistungsmerkmale die aktuelle Installation erfüllt und welche nicht. Die Testergebnisse sollten so detailliert ausfallen, dass Entwickler und Admin daraus schnell geeignete Anpassungs- und Optimierungsmaßnahmen abzuleiten vermögen.
Die Apache Software Foundation sendet aus ihrem Reich zu diesem Zweck das sehr ausgereifte Tool Jmeter [1] in die weite Entwicklerwelt. Stefano Mazzocchi, in Italien geboren und heute bei Google in den USA beschäftigt, hatte 1998 begonnen Jmeter zu entwickeln, um Lasttests am Apache-Tomcat-Server zu absolvieren. Anschließend führte Mazzocchi – seit 1999 Member des Project Management Committee (PMC) von Apache Jakarta – das Tool als Jakarta-Unterprojekt weiter. Seit 2011 besitzt Jmeter den Status eines eigenständigen Apache-Toplevel-Projekts. Als einer der wenigen Konkurrenten gilt Grinder 3 [2], den jedoch schon länger niemand mehr weiterentwickelt.
Von Jmeter erscheinen pro Jahr mehrere Versionen. In der aktuellen 2.13 unterstützt Jmeter von Hause aus die Protokolle HTTP und HTTPS, SOAP, FTP, JDBC, Mongo DB, LDAP, JMS, AJP, TCP sowie SMTP, POP3, IMAP und deren verschlüsselte Brüder. Der Schwerpunkt liegt sicher auf dem Lasttest an Webanwendungen. So existieren für das beliebte Blogsystem WordPress fertige Jmeter-Testpläne [3].
Als Installationsvoraussetzung nennt die Dokumentation eine Java-Laufzeitumgebung (mindestens Version 6, aber auch 8) und passende Treiber für die anzusprechenden Systeme. Die Funktionalität von Jmeter ist jedoch über Skripte in den verschiedenen Programmiersprachen und über Plugins [4] zum Beispiel für Selenium oder Hadoop-HDFS erweiterbar.
Nach Testplan handeln
Der Anwender ruf das Tool mit »jmeter.sh« (unter Windows: »jmeter.bat« ) im Verzeichnis »$JMETER_HOME/bin« auf. Dort führt es auch die Protokolldatei »jmeter.log« , die bei Fehlern zu analysieren wäre. Nachdem Jmeter gestartet ist, benötigt der Anwender einen Testplan. Dazu kann er fertige Vorlagen abändern, die im Verzeichnis »bin\templates« oder »printable_docs\demos« liegen. Am einfachsten rufen er »File | Templates« auf und wählt aus den angebotenen Vorlagen »Building a Web Test Plan« aus. Die Beispielvorlage setzt zwei Anfragen an den Host http://jmeter.apache.org und die Seiten »/« und »/changes.html« ab und stellt das Ergebnis als Graph dar.
Der zweite Weg zu einem Testplan ist, ein passendes Modell von Grund auf selbst anzufertigen. Testpläne sind in einem XML-Format ohne XSD-Schema verfasst. Es lässt sich aber zur Dokumentation per Stylesheet (»extras/schematic.cmd Testplan.jmx« ) in HTML umwandeln.
Ein mit Jmeter gelieferter Rekorder weist den dritten und meist komfortabelsten Weg zu einem Testskript. Zu Beginn trägt der Anwender in seinem Webbrowser den Jmeter-Server-Proxy mit Port »8888« und als »localhost« ein. Dann ruft er die Vorlage für den Testskript-Rekorder auf und startet ihn. Der zeichnet nun alle Aufrufe auf, die der User im Browser absolviert. Er kann manuell das Element Testskript-Rekorder dem Icon-Workbench hinzufügen mit »Add | Non-Test Elements | HTTP(S) Test Script Recorder« . Das ist vor allem bei komplexeren Seitenaufrufen mit Anmeldung hilfreich.
Nachdem die Aufzeichnung beendet ist, lassen sich die Seitenaufrufe, ähnlich wie bei den beiden anderen Wegen, in Richtung des gewünschten Ablaufs trimmen – also in erster Linie mit Variablen konfigurierbar machen, um den Testplan beispielsweise für verschiedene Umgebungen und Hostnamen mit passenden Parametern aufzurufen (Abbildung 1).
Testpläne erweitern
Die Anzahl der simulierten Nutzer legt Jmeter in Thread Groups mit einer eventuell Warmlauf- oder Wartezeit an. Die eigentlichen Anfragen heißen bei Jmeter Sampler. Deren Ergebnisse sollte der Tester durch Assertion auf Erfolg prüfen, um technische und fachliche Fehler unterscheiden zu können. Auch die Nutzung von Cookies, Logins und das Ausfüllen von Formularen sind möglich.
Die Logic Controller steuern die Abarbeitung einzelner Teile des Testplans. Das Laufzeitverhalten der einzelnen Threads lässt sich per Konfiguration beeinflussen. Die Listener-Elemente stellen die Testergebnisse als Grafik oder Tabelle dar (Abbildung 2). Parameter legt der Tester entweder als benutzerdefinierte Konfigurationselemente (im GUI: »User Defined Variables« ) am Anfang des Testplans fest oder gibt sie Jmeter als Umgebungsparameter mit. Im ersten Fall referenziert zum Beispiel »${host}« den Rechnernamen in anderen Elementen. Im zweiten Fall, bei »jmeter -Jhost=www.yyy.com« , übergibt man den Parameter mit »${__property(host) }« (ein per »$Variable« referenziertes Java-Property).
Die große Kunst besteht jetzt darin, den Testplan flexibel erweiterbar und einfach konfigurierbar zu gestalten, indem der Benutzer die Verbindungsparameter und Stellgrößen in Variablen auslagert [5]. Diese kann er leicht vor dem Aufruf anpassen, ohne jedes Mal den Testplan ändern zu müssen.
Verteilt testen
Für große Last- und Stresstests ist es sinnvoll und möglich, den Testplan von mehreren Jmeter-Installationen abarbeiten zu lassen. Die melden ihre Ergebnisse per RMI [6] an einen zentralen Jmeter-Berichtsserver, der ausschließlich für das Sammeln und Aufbereiten der Daten zuständig ist. Der Masterserver und die Slaveclients startet der Tester wie von einer Einzelinstallation gewohnt.
In der Datei »bin/jmeter.properties« des Masterservers trägt der Benutzer unter »remote_hosts« die IP-Adressen der Slaveclients ein oder übergibt sie auf der Kommandozeile zusammen mit dem Testplan:
jmeter -n -t script.jmx -R Slave1,Slave2,Slave3
Den auf dem Master geladenen Testplan startet er über das GUI des Masters entweder einzeln oder er verteilt und startet ihn über »Remote Start All« auf allen Slaveclients. »Remote Stop« beendet die Testaktivitäten wieder. Ein typischer verteilter Testaufbau schaut wie in Abbildung 3 aus. Der Benutzer sollte die Daten über die grafische Auswertung hinaus speichern, um die Ergebnisse für Dokumentations- und Vergleichszwecke zu archivieren.
Proxys, Protokollieren, Maven
Soll Jmeter Webseiten testen, die hinter einem Firmenproxy sitzen, muss das Tool diesen als Parameter mit auf den Weg bekommen:
jmeter -H My.Proxy.Server -P 8000 -u Username -a Password -N localhost
Wer Jmeter ohne Oberfläche starten will, um die Ergebnisse in einer separaten Datei abzulegen, fügt die Parameter »-n -t my_test.jmx -l log.jtl« hinzu. »jmeter -?« listet weitere Kommandozeilen-Parameter aus. Bei größeren Testplänen kann es nötig werden, die Speichereinstellungen für die Java-Laufzeitumgebung in der Startdatei zu optimieren – wie »HEAP« passend zur eingesetzten JVM.
Inzwischen hat das Projekt auch die TLS-Unterstützung verbessert, sodass der Testskript-Rekorder auch damit funktioniert. Soll der Lasttest im kontinuierlichen Integrationsprozess ablaufen, so gibt es für das Build-Tool Maven ein passendes Plugin [7]. Das kann das Konstrukt in Listing 1 in die »pom.xml« -Datei einbinden und konfigurieren.
Wer einzelne Protokolle der eingangs aufgezählten, beachtlichen Liste praktisch anwenden will, muss mindestens die minimalen Parameter der jeweiligen Konfigurationselemente [8] angeben, beispielsweise für JDBC oder SMTP die Verbindungsinformationen.
Listing 1
Maven-Plugin einbinden
01 <plugin> 02 <groupId>com.lazerycode.jmeter</groupId> 03 <artifactId>jmeter-maven-plugin</artifactId> 04 <version>1.10.1</version> 05 <executions> 06 <execution> 07 <id>jmeter-tests</id> 08 <phase>verify</phase> 09 <goals> 10 <goal>jmeter</goal> 11 </goals> 12 </execution> 13 </executions> 14 </plugin>
Falschmessungen vermeiden
Spätestens seit Heisenberg ist es Allgemeingut, dass die Messung selbst oft das Messergebnis beeinflusst. Praktisch kein Lasttest kann messbedingte Seiteneffekte und Messungenauigkeiten ganz vermeiden. Um die Auswirkungen zu minimieren, sollten Tester ihren Messungen eine Warmlaufphase gönnen und jede gewertete Messung wiederholen. Außerdem sollten sie die Last besser auf mehrere Slaves verteilen, damit nicht der einzelne Testclient zum Engpass wird.
Fazit
Apache Jmeter erweist sich in der Praxis als ein gut handhabbares Werkzeug, um einfache Lasttests durchzuführen. Es ist auch für größere verteilte Lasttests leistungsstark genug. Hier liegen klar seine Stärken. Fürs gezielte Auswerten der Tests und das grafische Aufbereiten der Ergebnisse ist der Benutzer dagegen auf externe Spezialwerkzeuge wie Excel oder Matplotlib angewiesen.
Die beiliegenden Vorlagen, Beispiele und Dokumentationen helfen beim Einstieg. Im Open-Source-Reich trifft Jmeter kaum auf ernsthafte Konkurrenten, sodass es sich unbekümmert auch beim Publikum kommerzieller Lasttestwerkzeuge als kostenlose und verlässliche Alternative empfehlen und etablieren kann.
Infos
- Jmeter: http://jmeter.apache.org
- Grinder 3: http://grinder.sourceforge.net
- Jmeter-Testvorlagen für WordPress: https://github.com/jmeter-templates/wordpress, http://blazemeter.com/blog/increasing-productivity-wordpress-site-when-using-blazemeter-its-easy-task
- Jmeter-Erweiterungen: http://jmeter-plugins.org
- Jmeter-Tipp-Sammlung: http://blazemeter.com/apache-jmeter
- Jmeter-Master-Slave-Test: http://jmeter.apache.org/usermanual/remote-test.html
- Jmeter-Maven-Plugin: https://github.com/jmeter-maven-plugin/
- Jmeter-Konfigurautionselemente: http://jmeter.apache.org/usermanual/component_reference.html









