Skalierbarkeit mit Gatling testen
Gatling Lasttests
Deine App läuft gut mit kleineren Customern, aber größere Customer bringen höhere Anforderungen mit. Diese Customer nutzen die App intensiver - sei es durch mehr Nutzer, ressourcenintensive Funktionen oder häufige Anfragen. Um sicherzustellen, dass deine App auch bei dieser höheren Last gut funktioniert, ist es wichtig, sie gründlich zu testen.
In diesem Blogbeitrag erfährst du, wie du mit Gatling testen kannst, ob deine App die Belastung durch größere Customer erfolgreich bewältigen kann.
Die Herausforderung: Mehr Last durch größere Customer
Größere Customer haben typischerweise:
- Mehr Nutzer, die gleichzeitig aktiv sind,
- komplexe Workflows, z. B. das Erstellen von Berichten oder Durchführung von Qualitätskontrollen,
- höhere Datenmengen und häufigere Abfragen.
Diese Faktoren können die Leistung deiner App stark belasten. Die Skalierbarkeit sollte getestet werden, bevor große Customer die App nutzen, um Engpässe frühzeitig zu identifizieren.
Warum Gatling?
Gatling hilft dabei, die Auswirkungen steigenden Traffics und intensiver Nutzung präzise zu simulieren. Zudem ist Gatling Open Source und lässt sich vielseitig einsetzen. Hier einige wichtige Vorteile:
- Realistische Lasttests: Simuliere viele gleichzeitige Nutzer und komplexe Interaktionen.
- Anpassbare Szenarien: Passe Tests an die spezifischen Anforderungen größerer Customer an.
- Echte Daten: Nutze Daten aus API-Antworten oder CSV-Dateien für realistischere Tests.
Dank der Maven- und Gradle-Plugins lässt sich Gatling leicht in neue oder bestehende Projekte integrieren. Einmal eingerichtet können Lasttests direkt über die Kommandozeile ausgeführt werden. Zudem kannst du mit Gatling in Java, Scala, Kotlin, JavaScript oder Typescript arbeiten - je nachdem, was am besten zu deinem Projekt passt.
In diesem Blogbeitrag wird Kotlin verwendet.
Lasttests für den Anstieg des Traffics und komplexe Workflows
Um zu testen, wie gut deine App mit der höheren Nachfrage durch größe Customer umgehen kann, musst du Test-Szenarien erstellen, die die Erhöhung des Traffics und komplexere Workflows simulieren. Größere Customer haben oft mehr Schritte und Aufgaben im Workflow, was zu einer höheren Belastung der App führt. Diese zusätzlichen Aufgaben erfordern mehr Datenverarbeitung und Ressourcen.
Hier sind einige kleine Code-Beispiele, die verschiedene Gatling-Techniken zeigen, die kombiniert werden können, um realistischen Lasttests zu erstellen:
- Session-Variablen aus API-Antworten speichern für spätere Anfragen nutzen.
- Loops über dynamische Werte aus vorherigen Anfragen.
- Feeder mit echten Daten, um unterschiedliches Nutzerverhalten zu simulieren.
- Benutzer-Injektionsprofile simulieren, wie Benutzerzahlen konstant bleiben oder steigen.
Diese Techniken lassen sich kombinieren, um Tests zu erstellen, die nicht nur Last simulieren, sondern auch echtes Verhalten realistisch abbilden.
1. Unterschiedliche Workflows für kleine und große Customer
Kleine und große Customer nutzen denselben Workflow, aber größere Customer erhalten mehr Aufgaben vom Server, die sie verarbeiten müssen. Die Anzahl der Aufgaben ergibt sich dynamisch aus der Serverantwort.
val customerScenario = scenario("Process tasks dynamically")
// 1. Initial query to get the list of tasks
.exec(
http("Get list of tasks")
.get("/tasks")
.check(status().shouldBe(200))
.check(jsonPath("$.tasks[*].id").findAll().saveAs("taskIds"))
// Saves all Task-IDs in the session
)
// 2. Process each received Task-ID
.foreach("#{taskIds}", "taskId").on(
exec(
http("Update task")
.post("/tasks/#{taskId}/complete")
.check(status().shouldBe(204))
)
)
Erklärung:
- Dynamische Workflow-Ausführung: Die Anzahl der Schritte ergibt sich aus der Serverantwort, nicht aus statischer Logik.
- Unterschiedliche Nutzerpfade: Kunden mit mehr Aufgaben erhalten automatisch mehr Workload, aber der Workflow bleibt für alle gleich.
- Nutzung von Session-Variablen: Die empfangenen Task-IDs werden gespeichert und für weitere Anfragen verwendet.
2. Testdaten aus einer CSV-Datei nutzen
Für realistische Tests können verschiedene Aufgaben aus einer CSV-Datei geladen werden. Jede Aufgabe wird dann durch die API bearbeitet.
val taskFeeder = csv("tasks.csv").circular() // Feeder loops through CSV file
val scenarioWithData = scenario("Use CSV data")
.feed(taskFeeder) // Load CSV data in the session
.exec(
http("Get list of tasks")
.get("/tasks")
.check(status().shouldBe(200))
.check(jsonPath("$.tasks[*].id").findAll().saveAs("taskIds")) // Saves all Task-IDs
in the session
)
.foreach("#{taskIds}", "taskId").on(
exec(
http("Update task")
.post("/tasks/#{taskId}/complete")
.body(StringBody("""{
"type": "#{taskType}", // Value for task type from CSV file
"priority": "#{priority}" // Value for priority from CSV file
}""")).asJson()
.check(status().shouldBe(204))
)
)
Erklärung:
- CSV-Feeder: Die Aufgaben-Daten
taskType
andpriority
werden aus der CSV-Datei geladen. - Session-Variablen: Durch das
feed(taskFeeder)
werden Daten aus der CSV-Datei in die Session geladen. - Verwendung in der Anfrage: Jede Aufgabe wird mit dynamischen Werten aus der CSV bearbeitet.
3. Setup für die Ausführung von Testszenarien
Jeder Gatling-Test benötigt eine Setup-Definition, um festzulegen, wie Nutzer simuliert werden. Hier wird zunächst ein bestehender Traffic von kleinen Customer beibehalten, während die Nutzerzahl für einen großen Customer über fünf Minuten hochskaliert wird:
init {
setUp(
smallCustomerScenario.injectOpen(
atOnceUsers(20) // 20 users for a small customer
).protocols(httpProtocol),
largeCustomerScenario.injectOpen(
rampUsers(100).during(5 * 60) // Ramp up from 20 to 120 users over 5 minutes
).protocols(httpProtocol)
)
}
Erklärung:
- Open Injection Model: Ankunftsrate der Nutzer wird über einen Zeitraum gesteuert. Hier wird die Erhöhung der Nutzerlast damit simuliert.
- Sofortiger Anstieg vs. Ramp-up: Kleine Customer beginnen sofort, die Basislast zu erzeugen. Große Customer rampen hoch, um zu simulieren, dass nicht alle Nutzer gleichzeitig starten.
- Warten auf Abschluss: Der Test wartet bis alle Nutzer aus beiden Szenarien ihre Aufgaben abgeschlossen haben.
Fazit
Mit Gatling kannst du sicherstellen, dass deine App auch unter steigender Last stabil und performant bleibt. Durch realistische Simulationen von Workflows, Nutzerdaten und steigender Nutzerzahl kannst du Engpässe frühzeitig erkennen und gezielt optimieren. Ein durchdachter Lasttest hilft dir, größere Customer zuverlässig zu bedienen, ohne dass die Performance leidet.
Praktische Tipps zur Umsetzung
Lasttests sind nur so wertvoll wie ihre Analyse. Stelle sicher, dass du neben den Gatling-Reports auch Systemmetriken wie CPU-Auslastung, Speicherverbrauch und Datenbanklast überwachst. Die gewonnenen Erkenntnisse helfen dir, Optimierungen gezielt anzugehen - sei es durch Caching, Datenbank-Tuning oder Skalierungsmaßnahmen!
Weiterführende Informationen
Falls du noch tiefer in das Thema Lasttest mit Gatling einsteigen möchtest, findest du hier einige hilfreiche Links:
- Gatling-Dokumentation: https://docs.gatling.io/
- Realistische Gatling-Tests schreiben: https://docs.gatling.io/tutorials/advanced/
- Arten von Lasttests: https://grafana.com/load-testing/types-of-load-testing/
Bildquelle: Gatling, aus der Presse-Seite