{"id":19282243,"url":"https://github.com/accso/performancetesting-example","last_synced_at":"2025-11-17T10:01:58.559Z","repository":{"id":150176810,"uuid":"53668620","full_name":"accso/performancetesting-example","owner":"accso","description":null,"archived":false,"fork":false,"pushed_at":"2016-08-07T15:10:28.000Z","size":2186,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-02-23T22:25:50.735Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/accso.png","metadata":{"files":{"readme":"README.md/Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-03-11T13:24:46.000Z","updated_at":"2016-07-22T10:43:04.000Z","dependencies_parsed_at":null,"dependency_job_id":"b128ae5a-5fe5-44bb-806d-63c34071592c","html_url":"https://github.com/accso/performancetesting-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/accso/performancetesting-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/accso%2Fperformancetesting-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/accso%2Fperformancetesting-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/accso%2Fperformancetesting-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/accso%2Fperformancetesting-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/accso","download_url":"https://codeload.github.com/accso/performancetesting-example/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/accso%2Fperformancetesting-example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":284861038,"owners_count":27075155,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-17T02:00:06.431Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T21:25:54.820Z","updated_at":"2025-11-17T10:01:58.524Z","avatar_url":"https://github.com/accso.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# README\r\n\r\n## Einleitung\r\n\r\nDie Demo-Anwendung zur Kundenverwaltung ist das System unter Test für die hier im Vordergrund stehenden zwei Gatling-Testszenarien _TestCreateCustomer_ zum Anlegen von Kunden mit ihren Produktfavoriten und _TestReadCustomers_ zum zufälligen Abrufen von Kundendaten.\r\n\r\nInsbesondere _TestReadCustomers_ realisiert ein Lasttestszenario, das die Demo-Anwendung ungesteuert mit maximaler Aufrufrate in den Überlastbereich bringt, um so die Grenzen der Software und Hardware auszuloten. Demgegenüber würden Performancetests ein vordefiniertes Belastungsmuster prüfen.\r\n\r\n## Voraussetzungen\r\n\r\n* **Docker-Installation**\r\nDie beschriebenen Performance-Installation wurde unter Windows 7 und Windows 10 mit Docker 1.11.2 (Docker Toolbox) erstellt.\r\n* **Java Runtime**\r\nDie instrumentierte Demo-Anwendung wurde mit Java 8 (1.8.0._92) getestet.\r\n* **Maven**\r\nDie Demo-Anwendung wurde mit Maven 3.3.9 gebaut.\r\n* **Demo-Anwendung**\r\nDie Quellen der Demo-Anwendung src im beliebigen Verzeichnis DEMOROOT.\r\n* **Docker-Konfigurationsdateien**\r\nDie Konfigurationen für die Docker-Infrastruktur `docker-data-from-host-application` der Demo-Anwendung im Verzeichnis DEMOROOT.\r\n* Eine Breitband-Internetanbindung zum Herunterladen der benötigten Maven-Artefakte und Docker-Images (ca. 2GB).\r\n\r\n\r\n## Überblick\r\n\r\nMit Hilfe von Docker entstehen einzelne Container, in denen die benötigten Anwendungen Logstash 2.3.2, Elasticsearch 2.3.0 und Kibana 4.5.1 laufen. Die Anwendungen laufen in ihren Containern unter ihren Standard-Ports und sind von außerhalb unter der IP-Adresse erreichbar, die Docker beim Start ausgibt, bspw. 192.168.99.100:\r\n\r\n![](images/Docker-Startup-Screen.png \"Docker-Startbildschirm\")\r\n\r\nDie Demo-Anwendung läuft neben den Docker-Containern auf dem Host:\r\n\r\n* Die Demo-Anwendung produziert die Logdaten außerhalb von Docker auf dem Host.\r\n* Der Logstash-Container mappt seine Daten vom Host.\r\n* Der Data-Only-Container hält Daten auch bei Beendigung der anderen Docker-Prozesse.\r\n\r\n![](images/Demo-Anwendung-Systemarchitektur.png \"Systemarchitektur der Demo-Anwendung mit Docker-Containern\")\r\n\r\n## Schritt-für-Schritt-Vorgehen\r\n\r\n* Start der Docker-bash und Navigation ins Verzeichnis `docker-data-from-host-application` \r\n* ELK-Stack starten durch Eingabe von `docker-compose up –d`\r\n    * Docker lädt die Images busybox, elasticsearch, logstash und kibana.\r\n    * Docker erzeugt die Images elkdata_image, elasticsearch_image und kibana_image.\r\n    * Docker fährt die ELK-Anwendungen als Services elkdata, logstash, elasticsearch und kibana in jeweils eigenen Containern hoch.\r\n    * Ergebnis: \r\nlogstash wartet auf die Logausgaben im Host-logs-Verzeichnis `src/workspace/performancetesting/logs` (im Container gemappt auf `/logstash/logs`).\r\n* Überprüfung der laufenden Installation\r\n    * Elasticsearch-Aufruf im Browser mit der Adresse: http://\u003cdocker-ip\\\u003e:9200/_plugin/hq.\r\n    * Ergebnis: Es sollte das Elasticsearch-Dashboard zu sehen sein. Das mitinstallierte ElasticHQ-Plugin erzeugt dieses Dashboard. \r\n* Starten der Demo-Anwendung\r\n    * In einer Shell Navigation ins Verzeichnis `src/workspace/performancetesting`.\r\n    * Aufruf von `mvn spring-boot:run` \r\n* Starten der Lasttests, zunächst Schreibzugriffe, dann Lesezugriffe\r\n    * In einer Shell Navigation ins Verzeichnis `src/workspace/performancetesting`. \r\n    * Aufruf von `mvn gatling:execute -Dgat-ling.simulationClass=de.accso.performancetesting.TestCreateCustomer`\r\n    * Aufruf von `mvn gatling:execute -Dgat-ling.simulationClass=de.accso.performancetesting.TestReadCustomers`\r\n* Zwischenstand:\r\n    * Die Anwendung schreibt in die in `src/workspace/performancetesting/src/main/resources/logback.xml` konfigurierte Log-Datei (`src/workspace/performancetesting/logs/performance.log`).\r\n    * Logstash überträgt die Daten in Elasticsearch.\r\n    * Im Elasticsearch-Dashboard sollte der Logstash-Index logstash-\\\u003cTagesdatum\\\u003e (Bsp.: logstash-2016.03.12) zu sehen sein, dessen Dokumentanzahl zunimmt.\r\n* Kibana-Auswertung durchführen\r\n    * Kibana im Browser mit der Adresse http://\u003cdocker-ip\\\u003e:5601 aufrufen\r\n    * Beim ersten Aufruf den Default-Index erzeugen (bietet Kibana direkt an): die Standardeinstellungen (logstash-* mit @timestamp) verwenden\r\n    * Anschließend steht Kibana für eigene Auswertungen zur Verfügung.\r\n    * Einsatz des vorkonfigurierten Dashboard: \r\n        * Kibana-Menü Settings-\u003eObjects-\u003eImport aufrufen\r\n        * Die Konfigurationsdatei `docker-data-from-host-application/configfiles/applicationdata-kibana-configuration.json` laden\r\n* Ergebnis:\r\nDas Dashboard “performanceapplication-dashboard” zeigt die Daten der letzten 5 Minuten in den vorkonfigurierten Ansichten (durch Festlegen der global konfigurierten Zeitspanne).\r\n    * Fallstrick 1: \t\r\nDeckt die konfigurierte Zeitspanne nicht die Zeitangaben der geladenen Daten ab, dann zeigt Kibana statt der Daten die Meldung „No results found“ an. In diesem Fall zuerst die globale Zeitfestlegung in Kibana mit den in Elasticsearch geladenen Daten abgleichen!\r\n    * Fallstrick 2: \t\r\nBietet der Bildschirm nicht ausreichend Platz zur Darstellung der geladenen Daten (z.B. weil das X-Achsen-Intervall sehr feingranular auf Sekunden eingestellt ist), dann zeigt Kibana „This container is too small to render the visualization“. In diesem Fall reicht es aus, den Betrachtungszeitraum zu verkleinern.\r\n\r\nGatling selbst hält übrigens gut aufbereitete Reports bereit. Einen ersten Überblick bekommt man in der Shell, hier am Beispiel des Kundendaten-Abrufszenarios:\r\n\r\n![](images/Gatling-Beispiel-Report.png \"Beispiel-Ergebnisausgabe von Gatling\")\r\n\r\nDetailliert aufbereitete HTML-Graphiken stehen im Target-Verzeichnis unter `src/workspace/performancetesting/target/gatling` bereit.\r\n\r\nFür kontinuierliche oder explorative Auswertungen bleibt hier aber ELK das Mittel der Wahl.\r\n\r\n## Ergebnisinterpretation\r\n\r\nAuf einem Entwicklernotebook wird der Lasttest mit der einfachen Demo-Anwendung vordergründig erstaunliche Ergebnisse ähnlich dem folgenden produzieren:\r\n\r\n![](images/Kibana-Dashboard.png \"Ergebnisse der Demo-Anwendung im Kibana-Dashboard\")\r\n\r\nDie Anwendung ist trotz simplen Aufbaus und einer In-Memory-Datenbank mit über 3 Sekunden mittlerer Latenzzeit unglaublich inperformant. Die Aufrufanzahl (untere grüne Graphik) zeigt die durch die beiden Testszenarien erzeugten Phasen. \r\n\r\nBeobachtung und Vermutung:\r\n\r\n* Während das Kundenanlegen kaum ins Gewicht fällt, führt das Kundenlesen schnell zu hohen Antwortzeiten und bestimmt maßgeblich die Quantilwerte.\r\n* Der steile Anstieg der zweiten Phase zeigt deutlich den Test-RampUp auf bis zu 20 parallele Nutzer.\r\n* Da das Notebook während des Tests zu 100% ausgelastet war, handelt es sich offensichtlich um einen CPU-Engpass.\t\r\n\r\n![](images/CPU-Auslastung-der-Demo-Anwendung-beim-Lesen.png \"CPU-Auslastung der Demo-Anwendung in der Phase Kundenlesen\")\r\n\r\nGrundsätzlich könnte der Engpass auch die Folge des stark vereinfachten Testaufbaus sein, in dem sowohl die Docker-Container als auch die Anwendung, als auch der Testtreiber um die Betriebsmittel konkurrieren. \r\n\r\nEin Vergleich mit der Anwendung auf einer 32-Kern-CPU-Maschine bestätigt allerdings die Vermutung, dass der Testlauf auf dem Entwicklernotebook keine gute Idee war:\r\n\r\n![](images/Anwortzeiten-mit-32-Kern-CPU.png \"Anwortzeiten der Demo-Anwendung mit 32-Kern-CPU\")\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faccso%2Fperformancetesting-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faccso%2Fperformancetesting-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faccso%2Fperformancetesting-example/lists"}