luni, martie 22, 2010

Optimizarea performantei unei aplicatii Web

Descriu in continuare o serie de unelte (biblioteci Java si tool-uri) folosite in optimizarea performantei pentru o aplicatie Web. Aplicatia are un spatiu limitat de memorie pentru a rula (< 64 M); dupa cateva zile aplicatia cade - Out of memory; aplicatia se incarca greu in browser.


Posibile probleme

1. problema: entitatile sunt folosite si in prezentare si sunt incarcate cu date; solutia: de folosit fetching in mapari - lazy loading pentru colectii in general

In mod implicit prin generare, maparile JPA contin lazy la nivelul colectiilor

2. problema: pe sesiune se pun inutil obiecte; solutie: sa se foloseasca scopul potrivit; daca sunt pe sesiune deja nu se mai pun

La nivel de session ma intreb mai intai daca sub atributul dat exista ceva (!=null); daca da nu fac nimic, daca nu pun valoare sub atribut

Unelte folosite

Glassbox - evidentierea problemelor din runtime

Un tool util in urmarirea aplicatiei in runtime si determinarea punctelor ei slabe in ceea ce priveste performanta. Se instalaeaza in acelasi app server cu aplicatia care se vrea testata si ofera o consola in care sunt logate problemele de performanta care apar. Ofera sugestii pentru rezolvarea lor - destul de utile. Este o aplicatie utila care evidentiaza corect problemele dar nu poate inlocui un profiler.

YSlow - optimizarea paginilor Web

O unealta care concretizeaza experienta acumulata de Yahoo in optimizarea paginilor web. Este un plugin de Firefox care sta alaturi de FireBug si arata ce bune practici sunt incalcate in paginile aplicatiei tale. In general recomandarile sunt: sa se minimizeze numarul de call-uri HTTP prin concatenarea de resurse: javascript, css, introducerea unor atribute in headerul HTTP pentru a se face cache la nivel de proxy, etc. Ofera chiar tool-uri care te pot ajuta in fixarea acestor proble. A fosst nevoie si deun filtro pentru a modifica Expire date pentru resursele statice.

JProfiler - profiling

Cel mai bun profiler pe care il stiu - cei care l-au creat au fost foarte inspirati. Arata in mod dinamic memoria HEAP, thread-urile, call-urile de metode si timpul lor de executie, thread-urile, etc. O unealta foarte utila in a vedea ce se intampla in codul aplicatiei tale in runtime. Evidentiaza clasele specifica de J2EE, permite introduerea de filtre doar pe clasele care ne intereseaza (face introspectie pe cele care ne intereseaza).

WAPT - load test tool

Inlocuitor pentru JMeter - loat test tool. Permite inregistrarea unui script care sa fie executat ulterior pe mai multe thread-uri. Poate simula in acest caz mai mullti useri care folosesc aplicatia furnizand astfel datele necesare pentru profiler. Am preferat WAPT in defavoare JMeter pentru usurinta in folosire - JMeter e mai usor de folosit programatic pentru nightly test, etc (inregistrarea scripturilor se face prin activarea unui proxy). WAPT poate fi folosit cu 20 useri pe o periaoda scurta de timp.

OSCache - cache in partea de prezentare

OScache permite cacahe pentru pagini (filtru) sau fragmente (librarie de taguri). Cache-ul se face dupa chei diferite care pot fi incluse in grupuri. Se paote face flush programatic pe keie, pattern de chei, grupuri sau la intreg cache-ul. Stocarea se poate face in file sistem sau in memori. Configurarea intr-un fisier de configurare - filtrul direct in web.xml.

Am preferat cache pe pagini - pagina principala in care sunt aratate toate articolele si cele in care se arata continutul articolelor. Au aparut probleme cu partea de securitate a aplicatiei si cu URL rewrite. Trebuie avut in vedere ca partea de administrare (aflata sub un user autentificat) nu trebuie sa intre in cache - un user nelogat poate vedea o pagina cu informatii disponibila doar userilor autentificati. O buna practica este selectarea foarte clara a paginilor care pot fi introduse in cache. Invalidarea cache-ului se face programatic la nivel de action in momentul in care se adauga un articol sau comentariu. Efectele sunt vizibile cu ochiul liber.

Folosirea de cache la nivel de fragmente de pagini este nefolositoare - as economisi doar timpul necesar randarii tag-urilor JSTL, deoarece call-ul spre /servici/DAO se face din action, care doar redirecteaza spre JSP. La nivel de pagini, cache-ul pot evita call-urile spre baza date in totalite (pana la invalidarea lui).

EHCache - cache la nivel de Hibernate

EHcache este folosit implicit de Hibernate ca cache de level 1 la nivel de Hibernate session. Pentru level 2 la nivel de session factory este nevoie de a configura explicit clasele care se vor cache-ui. Si in acest caz am preferat cache in file system. De asemenea cache-ul la niivel de query-uri trebuie configurat explicit pentru a fi creat. Pentru a verifica procesul de cache trebuie activat loggerul de ehcache. Configurarea de ehcache se face la nivel de fisier de configurare - numit implicit ehcache.xml.

Compass - index pentru search

Index la nivel de Hibernate - prin intermediul lui se indexeaza toate obiectele care sunt persistate (salvate/incarcate) in baza de date, oferind posibilitatea de a raspunde rapid la search-urile din aplicatie fara a mai face query-uri la nivel de baza de date. Clasele care se doresc indexate trebuie marcate (am ales fisiere de configurare pentrua nu introduce adnotari in entitati - prefer sa le generez pe cele de Hibernate de fiecare data cand schimb ceva in tabele). Indexul poate fi regenerat oricand programatic - si se reactualizeaza singur in runtime prin integrarea cu Hibernate. In spate foloseste Lucene pentru indexare - deci se vor face query-uri de tip Lucene pentru regasirea informatiilor.

Log4J

Pentru a verifica functionarea librariilor de cache, Log4J a fost activat si setat pe un nivel corestunzator. De asemenea am preferat sa fac cache in file sistem pentru a urmari efectiv cache-ul.

Alte unelte utile

Eclipse - debug - pentru a verifica daca se fac call-uri in layerele aplicatiei - thread-ul ramane blocat in breackpoint.
Firebug - analiza paginilor web - DOM, trafic, etc
WireShark - analiza traficului de retea - la un nivel foarte detaliat in tot stack-ul TCP-IP
Tomcat - un enviroment destinat numai testarii; in dezvoltare se foloseste Jetty

Solutii finale

- folosire de cache-uri la nivel de prezentare si de persitenta
- optimizarea incarcarii paginilor web generate

Pasi urmatori

Un increase de memorie si mutarea cache-urilor in memory
Optimizare riguroasa la nivelul query-urilor de Hibernate
Pooling - verificarea parametrilor pentru thread pool in app server si connection pool pentru baza de date
Eliminarea servlet filter nefolositi sau maparea lor pe url-uri mai stricte
Eliminarea librariilor inutile din classpath - pentru a evita Permsize exception
Scalabilitate - Teracotta, SpringS tc server

luni, martie 08, 2010

Interviu despre Java şi educaţie

Un fragment dintr-un interviu acordat pentru lec-academy.ro.

LEC Academy este un proiect Line Education Center care are ca scop sa va aduca zilnic cate un tutorial video sau scris despre Java, PHP, Microsoft Office, dar si articole cu noutati din industria IT. Prezentam un fragment, restul interviului il puteti urmari lec-academy.ro


Ce sfaturi ai pentru cineva care ştie elementele de baza în programare şi vrea să “se apuce” de java?

Să înceapă să foloseasca limbajul Java în viaţa de zi cu zi în dezvoltarea de aplicaţii efective, începând de la API-ul standard dat de JSE şi continuând cu bibliotecile şi framework-urile enterprise. Să citeasca puţin şi să scrie mai mult cod. O bună idee este să disece o aplicaţie deja făcută în Java chiar dacă este imperfectă şi să înveţe din experienţa altora. Să se implice atât în partea de dezvoltare de aplicaţii pentru desktop cât şi în partea de Web pentru a-şi lărgi domeniul de experienţă. Să se acomodeze cu tool-urile specifice limbajului: IDE-uri, unelte de build, servere de aplicaţii, etc. Să nu se limiteze doar la cunoaşterea teoretică!

Care este, în opinia ta, diferenţa dintre un developer bun şi unul mediocru?

Consider că un adevărat dezvoltator, pe care eu îl numesc “pur sange” este cel care şi-a făcut o profesie (meserie) din programare. În sensul că nu este ataşat doar de un job sau o firma sau un proiect ci de limbaj, tehnologii, şi programare în general, cele din urmă având un scop şi o durată de viaţă mult mai mare decât primele. Desigur, e imposibil să ştii totul. Părerea mea este că ideea de “cache levels” este aplicabilă şi în afara programării. Întotdeauna avem un set de informaţii foarte des folosite pe care le ţinem în memorie la îndemână, dar ne vine uşor să căutăm dupa alte informaţii mai rar folosite pe Web, în cărţi, etc. Dar în general un bun programator are o înţelegere mai profundă a limbajului şi a tehnologiilor venită din pasiunea pentru programare deoarece este afectiv legat de acestea şi drept consecinţă acumulează mai uşor cunoştinţe.

Ce sfaturi ai avea pentru cineva care este începător în “ale programării” indiferent de limbajul folosit? Cum ajungi un developer bun?

Sunt un susţinător al experienţei (şi oarecum împotriva sistemului academic) pe care o consider singura care poate să dea un folos efectiv învăţării. Teoria foarte rar are o aplicabilitate practică imediata mai ales dacă este adusă la un grad înalt de formalizare aşa cum se întâmplă în facultate. Consider ca anii consumaţi în facultate aproape inutil trebuie să fie răscumpăraţi prin ani de munca în producţie folosind efectiv tehnologii, unelte, etc.


Source: http://lec-academy.ro