2012. október 24., szerda

DynaTrace - A feltárt szerver oldali hibák 2.

Az előző post folytatásaként ismét néhány jellegzetes hibatípust gyűjtöttem össze amelyekkel jómagam foglalkoztam a stabilizációs projekt kapcsán. Hát igen, a DynaTrace ezen hibák megtalálásában is elég hasznosnak bizonyult, nézzük is meg hogy hogyan segített.

Hiányzó TimeOut-ok

Sok helyen találkoztam azzal, hogy a WebService, EJB, URLConnection vagy DB lekérdezéseknél nem voltak timeout-ok definiálva. A timeout-ok hiánya néha komoly stabilitási problémákhoz is vezetett, pl. többször is előfordult, hogy egy belassult web-szolgáltatás miatt a kérések feltorlódtak így a válaszidők is megnövekedtek. Ha már a timeout-okat állítgatjuk, a programozott (java kódbeli) megadás helyett érdemes inkább a konfigurációs paraméterrel való megadást választani, így akár futásidőben is módosíthatjuk az értékét.

Ahogy az alábbi ábra is mutatja, a timeout jellegű hibákat a DynaTrace segítségével elég egyszerűen be lehet azonosítani!


Prepared Statement problémák

Szintén gyakori eset, hogy az SQL lekérdezések paraméterei string konkatenációval voltak beillesztve a PreparedStatement-nél preferált paraméter binding helyett. Ezzel két probléma is van, egyrészt SQL injection-ra adhat lehetőséget másrészt a statement cache-t nem tudjuk majd jól kihasználni.

A lekérdezések végrehajtása alapvetően 2 fázisra osztható az előkészítésre és a paraméterek behelyettesítésével történő végrehajtásra. Az előkészítés egy cpu igényes művelet, ami minden statement legelső végrehajtásakor lefut. Ez a fázis a parszolás, a szintaktikai ellenőrzés és fordítás valalmint a végrehajtási terv elkészítésének a lépéseit tartalmazza. Az előkészített statement, a db connection-onként nyilvántartott statement cache-ben eltárolódik és amíg ebben a cache-ben megtalálható, addig a következő végrehajtások során csak a paramétereket kell behelyettesíteni, az erőforrás igényes előkészítést már nem kell újból végrehajtani.

Nézzünk erre egy példát! Vegyük a "SELECT ID id, DESCRIPTION desc FROM mytable WHERE BL=? ORDER BY desc" lekérdezést, ahol is helyesen a WHERE feltételnél található paraméter nincs beégetve, így ebben a formában a lekérdezés a statement cache-ben csak 1 helyet foglal, függetlenül attól hogy milyen paramétert használunk a lekérdezés során. Az alábbi DynaTrace-el beazonosított SQL lekérdezés pedig a kerülendő változat, miszerint ugyanaz a lekérdezés 8 helyet foglal el a statement cache-ben mivel a paraméter be lett égetve a lekérdezésbe.


Érdemes tudni, hogy a WebSphere alkalmazás szerver alatt a prepared statement cache size alapértelmezett értéke 10, JBoss alatt pedig ha nincs definiálva akkor 0, így ennek az értékét még akkor is érdemes megnövelni ha egyébként paraméterezett sql-eket használtunk!

A statement cache pontos bekonfigurálásához érdemes monitorozást végezni a WebSphere admin console integrált IBM TivoliPerformance Viewer vagy a DynaTrace segítségével a Prepared Statement Cache Discard Count PM-re feliratkozva. Sőt a DynaTrace ezen felül lehetőséget biztosít a parszolás nélkül végrehajtott lekérdezések arányának a monitorozásához is az Executions without parse ratio metrika segítségével.

Java implementációs hibák sokasága

A konfigurációs problémák mellett rengeteg java implementációs hiba is napvilágra került, éppen csak néhány példát megemlítve:

  • Néhány lapozó komponens lekérte az összes rekordot, nemcsak az adott oldalon megjelenítendőket.
  • Explicit garbage collector hívások a Java kódban.
  • Túl gyakori és felesleges Runtime.exec() hívások.
  • Le nem kezelt (és néha a felületre is kijutott) kivételek.
  • Memória szivárgások. (Memory Leak)
  • Custom megoldások implementációs hibái: Saját DB Connection Pool szinkronizációs és logikai hibák.

Ne maradj le a folytatásról sem!


2 megjegyzés:

  1. Az explicit gc és a Runtime.exec() bizony elég meredek dolgok. A saját DB connection pool pedig inkább arról árulkodik, hogy a készítők azt hitték, hogy bármiből jobbat tudnak írni. (és ez nem meglepő módon nem sikerült) Miért nem egy létezőt egészítettek ki a saját igényeiknek megfelelően? (bár ez csak költői kérdés)

    VálaszTörlés
    Válaszok
    1. Így leírva persze triviálisnak tűnik, de banki környezet révén a kódbázis hatalmas és egy része bizony elég régi is, továbbá a külső beszállítók is elég sokmindent behoztak ide komolyabb ellenőrzések nélkül. Szóval én nem csodálkoztam, hogy ilyenek is becsúsztak.

      A custom db connection pool szintén egy legacy dolog volt amihez senki nem akart hozzányúlni, amíg a lehalások egy részét a DynaTrace segítségével rá nem bizonyítottuk...

      Törlés