2013. szeptember 26., csütörtök

HOUG Szakmai nap 2013 - Rendszerhangolás a hardvertől az alkalmazásig

Előadóként meghívást kaptam a HOUG 2013-as szakmai napjára, ahol a Java szekcióban a szerver oldali optimalizálásról fogok egy 30 perces előadást tartani. A rendezvény 2013. október 9-én, a Rubin Wellness & Conference Hotel-ben kerül megrendezésre. A részvétel ingyenes, csak egy rövid előzetes regisztráció szükséges.


Az előadásom tartalma:
  • A JSF működése (röviden…)
  • Terheléses tesztek készítése JSF alapú web-alkalmazásokhoz
  • Problémák a terheléses tesztekkel
  • Az alkalmazások gyenge pontjainak beazonosítása
  • Nézzük meg a gyakorlatban…
  • A performancia és stabilitási problémák megelőzése

A prezentációm pedig itt érhető el!

2013. szeptember 14., szombat

JMeter - JSF alkalmazások terheléses tesztelése 2.

Egy korábbi bejegyzésben már írtam a JMeter általános használatáról, most pedig az előző elméleti ismeretekre építve kifejezetten a JSF-es web-alkalmazások JMeter-es terheléses teszteléséről lesz szó. Kezdjünk is neki!

Először is felvettem a szükséges JMeter konfigurációs elemeket, majd a JMeter Proxy Server segítségével rögzítettem egy tesztesetet, ami két HTTP kéréses keresésből állt. Az első kérés egy HTTP GET volt amivel lekértem a /CustomerSearch/search.jsf oldalt. Ez volt a JSF terminológia szerint az initial request, amikor is a szerver oldalon felépül a JSF komponensfa. Ezután kitöltöttem keresés űrlap mezőit majd egy HTTP POST kéréssel átküldtem a szervernek az adatokat és válaszként megkaptam a keresési eredményeket. Ez a második kérés már egy JSF postback volt, amihez az űrlap rejtett mezőjébe generált JSF komponensfa azonosítója, a viewStateId is elküldésre került.

A szkriptelési feladatunk, hogy a teszt futtatásakor a viewStateId-t mindig aktualizáljuk, mivel az minden lefutáskor más értéket fog kapni!

Az első megoldás az alábbi ábrán is látható JMeter Post Processor, a Regular Expression Extractor használata lehetne, miszerint az initial kéréshez tartozó válasz forrásából kinyerjük a javax.faces.ViewState értékét, majd a JAVAX_FACES_VIEWSTATE változóba eltárolva, a postback kérésnél a ${JAVAX_FACES_VIEWSTATE} kifejezéssel passzoljuk tovább!


Ez így elsőnek jónak tűnik, de mi lehet ezzel a probléma? A tapasztalat azt mutatja, hogy a JSF-re épülő keretrendszerek néha több sorba is megtörik a viewStateId átadására használt rejtett input mezőt, pl. a következőképpen:

<input id="javax.faces.ViewState" 
name="javax.faces.ViewState" type="hidden" value="aCe2XnokY5W3qRKTuTgT12YSQ0gxrqOMV9PcIU3FrDsUykah
" />

Ez azért probléma, mivel a JMeter-es reguláris kifejezéseket nem tudunk több sorban elhelyezkedő inputra illeszteni. De akkor hogy szedjük ki a viewStateId? Aki ismeri a JMeter eszköztárát annak a válasz egyszerű, a reguláris kifejezés helyett használjuk az XPath Extractor Post Processor-t az alábbi ábra szerint.


Ezek után már tényleg nincs más dolgunk, mindössze annyi, hogy a második postback kérésnél cseréljük le a beégetett viewStateId-t, az XPath kifejezésnél megadott változóra.


A folytatásban pedig arról fogok írni, hogy milyen előnyökkel jár, ha a dynaTrace-t a szoftverfejlesztési folyamatainkba is beillesztjük, legyen szó a fejlesztői ill. teszt eszközökről vagy egy CI platformról!

2013. szeptember 3., kedd

JMeter - JSF alkalmazások terheléses tesztelése 1.

Nemrég JSF-es web-alkalmazások tesztelésével és az eredmények dynaTrace-es kiértékelésével foglalkoztam a Raiffeisen Banknál, de a Szerencsejáték Zrt-nél, a Magyar Közút-nál valamint a ShiwaForce-nál is tartottam oktatásokat mind a JMeter használatáról mind pedig a teszteszközök (Selenium, JMeter, LoadRunner, JUnit) dynaTrace-es integrációjáról. Így következő bejegyzésekben erről a témáról és a dynaTrace tesztelési folyamatokba való illesztéséről fogok írni.

Még mielőtt nekikezdenénk a JSF alapú alkalmazások teszteléséhez érdemes megérteni a JSF működését, amihez az alábbi JSF életciklus ábra lesz a segítségünkre.


A JSF esetében alapvetően kétfajta kérés létezik, az initial és a postback. Az initial request (HTTP GET) hatására a szerver oldalon létrejön a kért oldalhoz tartozó komponensfa, melynek a csomópontjai az oldalon található elemek lesznek (UIForm, UIOutput, UIInput, stb...). Az initial kérések során csak a Restore View és az Render Response fázis fog lefutni, azaz felépül a komponensfa (+ eseménykezelők, validátorok, konverterek jóváhagyásra kerülnek, majd a view elmentésre kerül a FacesContext-be) ami alapján lerendelődik a HTML oldal. Postback kérések esetén tipikusan egy form mezői kerülnek átküldésre a szerver oldalra (HTTP POST), ahol létezik már az oldalhoz tartozó komponensfa, egy korábbi initial kérés következtében. Alapesetben a postback kérések elküldésekor mind a 6 JSF fázis lefut, ahol is a komponensfa aktualizálása mellett a megfelelő lépések után a managed bean-ekbe beíródnak az értékek.

A komponensfát legtöbbször a szerveroldali webes session-ban tároljuk és az ehhez tartozó azonosítót rejtett mezőként adjuk át az oldalon. Erre azért van szükség mert a HTTP protokoll állapotmentes és az azonosítás miatt a postback kérésekkel mindig továbbítani kell az initial kéréssel létrehozott komponensfa id-ját, ami általában így néz ki:

<input id="javax.faces.ViewState" name="javax.faces.ViewState" type="hidden" value="abcdefghijklmn123456" />

Miért is kell ezeket tudnunk a teszteléshez?

Azért, mert a rögzített tesztek HTTP kéréseinél, az elküldött javax.faces.ViewState paraméterek értéke már nem lesz érvényes a teszt futtatásakor, így azokat szkriptelve mindig aktualizálni kell. A következő cikkben pedig ennek a gyakorlati módját fogom megmutatni.