Christian Renner (ch12r)

Continuous Penetration mit Cruisecontrol, Ant und JMeter

Continuous Penetration?

Wer bei dieser Überschrift verzweifelt in der Tag-Line nach sexistischen Wörtern sucht, ist auf dem Holzweg.

Nein, das ist kein Wort aus dem Bereich “Schweinkram von Onkel Heinz”, sondern beschreibt viel mehr eine Vorgehensweise aus dem Bereich Testing und Quality Assurance (QA). Im Rahmen dieses Artikels möchte ich gerne festhalten, wie mit Hilfe eines Continuous Integration Prozesses, die Qualität einer PHP-Anwendung bezüglich der Performance unter Vollast gemessen und analysiert werden kann. Hierzu kommen im wesentlichen drei Tools zum Einsatz:

Um später noch einmal auf den Begriff “Continuous Penetration” zurückzukommen, möchte ich zunächst dessen Daseinsberechtigung, anhand eines Szenarios beschreiben.

Das Szenario

Auf einem Webserver eines beliebigen Webhosters haben wir eine eigens geschriebene PHP-Anwendung mit einer Anbindung an eine MySQL-Datenbank am Laufen. Diese Web-Anwendung ist gleichsam unsere persönliche Homepage und – da wir alles selbst programmiert haben – unser größter Stolz. Beziehungsweise war sie es das die längste Zeit. Bis vor kurzem die ganze Sache so unperformant geworden war, dass der Server angefangen hat zu streiken:

[Mon Dec 08 19:45:40 2008] [error] [client xxx.xxx.xxx.xxx]
     SystemException in API_Linux.cpp:172: setuid() failed:
     Resource temporarily unavailable
[Mon Dec 08 19:45:40 2008] [error] [client xxx.xxx.xxx.xxx]
     Premature end of script headers: index.php

Getestet haben wir unsere Anwendung immer auf einer lokalen Xampp-Installation, wo uns nie großartige Ungereimtheiten aufgefallen sind. Auch als wir die Seiten auf den entfernten Rechner geladen hatten, lief eigentlich immer alles problemlos. Die oben stehende Fehlermeldung aus dem error_log des Servers sagt jedoch etwas völlig anderes. Aus ihr geht hervor, dass der Webserver wegen Überlastung seinen Dienst quittiert hat. Sämtliche Domains des Fahnenflüchtigen gaben daraufhin nur noch “500 Internal Server Error” von sich zu hören.

Benchmarking mittels Continuous Integration

Kurzfristig hilft, die Anzahl der zur Verfügung stehenden Prozesse, sowie die CPU- und Arbeitsspeicherkapazitäten zu erhöhen. Langfristig empfiehlt es sich jedoch die Performance einzelner Teile der Anwendung zu messen, um somit die “schuldigen” Codefragmente zu lokalisieren und daraufhin optimieren zu können.

Hierzu drängt sich JMeter als Benchmarking-Tool geradezu auf. Mit dessen Hilfe lassen sich sehr einfach und schnell Testcases erstellen, um die eigene Anwendung Schritt für Schritt, Seite für Seite, Usecase für Usecase zu “penetrieren”. JMeter ist komplett in Java geschrieben und lässt sich sowohl über eine GUI als auch mittels der Kommandozeile ausführen. Für letzteres bietet sich die Erstellung eines Ant-Skriptes an.

Für das Testen können verschiedene Protokolle genutzt werden: HTTP(S), SOAP, JDBC – um nur ein paar zu nennen. Möchte man die Anwendung nun oben geschildertes Szenario testen, bietet sich das Testen per HTTP-Requests an. Hierfür lässt sich konfigurieren, welche Parameter per GET bzw. POST übergeben und in wie vielen Threads dieser Test ausgeführt werden soll. So kann man sich dann seitenweise anhand der Use-Cases durch die Anwendung hangeln. Da sich die Testszenarien speichern lassen, kann man diese zu jeder Zeit wiederholen. Hierfür sollte man Zeiten wählen, an denen nicht viel auf dem Server los ist. Auch mit der Anzahl der Threads, also dem simulierten Nutzeraufkommen, sollte man sich langsam einer oberen Grenze annähern, an welcher der Server zwar ausgelastet ist, aber noch nicht zusammenbricht.

Möchte man so einen Performance-Test in regelmäßigen Abständen und automatisiert wiederholen, bietet sich der Einsatz von Cruisecontrol an. Hiermit lässt sich zu bestimmten Zeiten  und abhängig von definierten Konditionen (z.B. Änderungen in einem SVN-Repository) die Ausführung von Ant triggern. Dadurch lässt sich das Ausführen eines Benchmarks trotz unveränderter Codebasis vermeiden. Ein weiterer Vorteil ist, dass CruiseControl arbeiten kann, wenn kein anderer Nutzer auf der Seite zugegen ist – sprich: Nachts.

Die Ergebnisse des Messvorgangs lassen sich dann von der Publishing-Komponente von CruiseControl nach verrichteter Arbeit veröffentlichen und somit einer – falls vorhanden – Arbeitsgruppe zugänglich machen.

Ich denke, dass gerade im Kontext von Web-Anwendungen, innerhalb dessen die Antwortzeiten zwischen Server und Client eine maßgebliche Größe sowohl in der Quality-of-Service-Bewertung als auch aus Usability-Sicht darstellt, es durchaus gerechtferigt einen gewissen Overhead – bestehend aus der Installation und Konfiguration von CruiseControl – zu generieren. Hat man sich dazu durchgerungen, lohnt sich unbedingt auch ein Blick auf PHPUnit, welches ebenfalls wunderschön mit CruiseControl zusammenspielen kann.

This entry was posted in Development and tagged , , , , , , , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared.

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="">