Load Tests mit Microsoft Azure
In den letzten 2 Wochen habe ich mich mit Load Test mit Microsoft Azure beschäftigt und sehr viel gelernt. In diesem Artikel fasse ich meine Erfahrungen in der Hoffnung zusammen, dass sie für den einen oder anderen Entwickler ebenfalls interessant sind.
Load Tests mit Microsoft Azure
Bevor man mit einer neuen Webapplikation live geht, sollte man immer einen Load Test machen. Bei so einem Test wird eine große Last auf das neue System simuliert. In der Regel versucht man herauszufinden wie viele gleichzeitige Benutzer das System verträgt und ab wann Antwortzeiten massiv einbrechen. Weiters kann man so herausfinden wie das System auf den Ansturm reagiert.
Kontext
Die Vergangenheit hat gezeigt, dass es neue Software immer wieder in die Schlagzeilen schafft. Gamer kennen das Problem: das neue Spiel wird freigeschaltet und das erste das passiert ist, dass die Login-Server zusammenbrechen. Entweder ist das Service dann komplett offline, oder es muss mit langen Wartezeiten gerechnet werden.
Damit uns das nicht passiert wollen wir vorab herausfinden wie das System mit 10, 100, 1000 oder 10000 gleichzeitigen Benutzern reagiert und ab wann mit Problemen zu rechnen ist. Als Ergebnis hat man nun nicht nur eine Ahnung davon, was die Software an Last schafft, man kann auch auf Seiten der Infrastruktur gegensteuern. Beispielsweise lässt man das System in der Cloud skalieren. Das heißt, ab einer bestimmten Anzahl an gleichzeitigen Benutzern werden neue Instanzen hinzugeschaltet beziehungsweise bei sinkenden Benutzerzahlen wieder abgeschaltet.
Azure
Azure unterstützt die Entwickler mit einem sehr einfachen Tool. Man erstellt eine neue Azure Load Test Instanz im eigenen Tennant, lädt ein JMX Script hoch und stellt ein über wie viele Instanzen dieses gleichzeigt ausgeführt werden soll. Danach klickt man nur noch auf „Run“ und man bekommt eine schöne Auswertung der Ergebnisse. Be bedarf kann man Logs der Instanzen die von dem Test verwendet werden hinzuschalten. So sieht man auch beispielsweise den Datentransfer, Ressourcen Auslastungen und Anzahl an Requests über die Zeit des Tests. Genaue Details wie Fehlermeldungen findet man dann in den einzelnen App Service Instanzen.
Das klingt nun recht einfach, doch was ist eigentlich ein JMX Script und woher bekommt man dieses?
JMX
Der aufwendige Teil beim Load Test ist die Erstellung eines JMX Scripts. Dabei handelt es sich um das Open Source Programm Apache JMeter, welches für die Erstellung von Load Tests und deren Auswertung erstellt wurde. Das JMX Script ist eine xml Datei mit Anweisungen, welche Requests gemacht werden sollen und mit welchen Daten diese aufgerufen werden. Dabei ist man auch für dynamische Webseiten gerüstet, es lassen sich Response Daten auswerten und diese Daten für folge Requests verwenden. Beispielsweise lassen sich so dynamische Login Informationen wie Session IDs oder JWT Tokens auslesen und weiter verwenden.
Wie erstellt man JMX Scripts?
Apache JMeter bietet eine grafische Oberfläche über die man diese Scripts durch vorgefertigte Elemente zusammenstellen und konfigurieren kann. Weiters kann man diese dort auch gleich testen. Es besteht auch die Möglichkeit einen Recorder zu definieren und Aktionen aus einem Browser oder Requests anderer Applikationen wie Postman aufzunehmen. Danach ist aber bei dynamischen Applikationen immer ein manueller Aufwand nötig. Klickt man sich nur durch eine statische Homepage reicht das aus.
Beispiel
Im folgenden zeige ich anhand eines einfachen Beispiels wie ich mir für den Test eines API Endpoints ein JMX Script gebaut habe. Die API kann nur mit einem gültigen JWT Token aufgerufen werden, weshalb der Test aus zwei Schritten besteht:
- JWT Token vom Login Server holen
- API Endpunkt aufrufen
Ich erstelle ein neues Apache JMeter Projekt und füge dort in der Thread Gruppe zwei HTTP Requests ein.
Den ersten Request nenne ich „GetJWTToken“ und ich setze für den Server Name die Domain des Login Servers und bei dem Pfad den Pfad für das JWT Token ein. Die nötigen Login Informationen werden als Parameter mit übergeben.
Als Antwort kommt bei dem Request ein JSON, in dem unter anderem das JWT Token steht. Genau dieses muss nun für den API Request extrahiert werden. Das funktioniert mit einem JSON Extractor. Wird dieser konfiguriert wie im Bild erkennbar, dann wird der Wert access_token aus dem JSON in die Variable auth_token geschrieben.
Der zweite Teil ist der API Request. Wieder erstelle ich einen HTTP Request und setze Domain und Pfad. Sofern weitere Informationen für diesen POST Request nötig sind setzt man diese als Parameter oder gleich als Body Data. In meinem Fall ist das ein JSON.
Noch funktioniert der API Request nicht. Jeder Versuch endet mit einem 402 HTTP Response, da die Logindaten nicht korrekt sind. Wir müssen noch das JWT Token im Header mit übergeben. Dazu erstelle ich ein BeanShell Pre-Prozessor mit folgendem Code:
Mit diesem Script wurde der Inhalt der Variable auth_token dem Authorization Header als Bearer Token mit übergeben. Nun klappt der API Request.
Den Test kann man nun lokal mit der Software testen. Hat alles geklappt kann man bei der Thread-Gruppe einstellen wie viele dieser Requests gemacht werden sollen. Azure Load Tests schlägt 250 vor.
Das JMX Script kann nun ins Azure Portal hochgeladen werden und dort auf beliebig vielen Instanzen ausgeführt werden.
In meinem Beispiel sieht man auf den Screenshots auch noch einen Recording Controller und einen Test Script Recorder. Damit lassen sich alle Requests die vom System gemacht werden aufzeichnen. D.h. man muss die einzelnen HTTP Requests nicht selber manuell anlegen. Für statische Seiten super, sobald dynamische Daten wie eine Session ID im Spiel sind müsste man diese noch so konfigurieren wie ich gezeigt habe (Session ID aus dem ersten Response speichern und für jeden weiteren Request verwenden). Damit das Recording klappt muss im Browser ein Proxy auf localhost und Port 8888 konfiguriert werden. In Firefox sieht das so aus:
Für Postman wäre die Konfiguration wie folgt korrekt:
Fazit
Nach anfänglichen Schwierigkeiten mit der neuen Software JMeter und dem mir zuvor unbekannten JMX Scripts habe ich gelernt meine komplexe Anforderung zu meistern und kann nun für dynamische Webseiten JMX Scripts erstellen. Einmal in Azure eingebunden lassen sich so schnell Erkenntnisse über die eigene Applikation gewinnen und Todos ableiten um auch für einen großen Ansturm gerüstet zu sein.