analisi prestazionale applicazione grails

12
ANALISI PRESTAZIONALE APPLICAZIONE GRAILS Descrizione Applicazione e Tecnologie utilizzate L’applicazione oggetto del test è stata realizzata in Grails 1.3.6, per il database è stato utilizzato MySQLServer 5.0. Il DB consta di tre tabelle (utente, proprietario, auto), ma in fase di test ne sono state utilizzate solo due (Utente per la login, proprietario per l’aggiunta di un nuovo record e per la lista). Il deploy dell’applicazione è stato fatto su Apache Tomcat 6.0 residente su una workstation Window XP, la stessa su cui è presente il DB. I test sono stati effettuati da PC remoti utilizzando una LAN isolata, per evitare che i risultati potessero essere falsati da un sovraccarico del traffico di rete. Per il monitoraggio del comportamento dell’applicazione è stato utilizzato JMeter 2.4 Configurazione Apache Jmeter JMeter è tool opensource sviluppato dalla Apache Software Foundation che permette di effettuare test di carico di qualsiasi tipologia di software, comprese le Web Applications. È possibile simulare la concorrenza attraverso i Threads permettendo quindi di misurare la performance al variare del carico attraverso la generazione di valori statistici come la media, la mediana, la varianza e il throughput. È possibile scaricare l'ultima versione stabile (2.4) dal sito ufficiale http://jakarta.apache.org/jmeter/ . Per lanciare il programma è necessario eseguire il file jmeter.bat presente nella cartella bin. Prima di tutto bisogna creare un Test Plan che descrive gli step da seguire per l'esecuzione del Test. È possibile configurare i seguenti parametri: Name: ciascun piano di test viene identificato con un nome User Definned Variables: è possibile associare al piano di test n variabili che possono essere richiamate all'interno del test; Run Thread Group consecutively: è possibile stabilire se i thread (utenti virtuali) devono essere avviati in modalità sequenziale (al termine di un thread viene avviato il successivo) oppure in modalità parallela (viene lanciato il primo, dopo k secondi viene lanciato il secondo, dopo 2k secondi il terzo e così via); Library: è possibile aggiungere delle classi o dei pacchetti jar al classpath. Nei test effettuati si è provveduto solamente a specificare il Name, che comparirà nel menù ad albero sulla sinistra, lasciando invariate le altre opzioni.

Upload: marcomarinucci

Post on 29-Jun-2015

289 views

Category:

Documents


0 download

DESCRIPTION

How to all'utilizzo e alla configurazione di Jmeter

TRANSCRIPT

Page 1: Analisi Prestazionale Applicazione Grails

ANALISI PRESTAZIONALE APPLICAZIONE GRAILS

Descrizione Applicazione e Tecnologie utilizzate

L’applicazione oggetto del test è stata realizzata in Grails 1.3.6, per il database è stato utilizzato

MySQLServer 5.0. Il DB consta di tre tabelle (utente, proprietario, auto), ma in fase di test ne sono

state utilizzate solo due (Utente per la login, proprietario per l’aggiunta di un nuovo record e per la

lista).

Il deploy dell’applicazione è stato fatto su Apache Tomcat 6.0 residente su una workstation

Window XP, la stessa su cui è presente il DB.

I test sono stati effettuati da PC remoti utilizzando una LAN isolata, per evitare che i risultati

potessero essere falsati da un sovraccarico del traffico di rete.

Per il monitoraggio del comportamento dell’applicazione è stato utilizzato JMeter 2.4

Configurazione Apache Jmeter

JMeter è tool opensource sviluppato dalla Apache Software Foundation che permette di effettuare test di carico di qualsiasi tipologia di software, comprese le Web Applications. È possibile simulare la concorrenza attraverso i Threads permettendo quindi di misurare la performance al variare del carico attraverso la generazione di valori statistici come la media, la mediana, la varianza e il throughput.

È possibile scaricare l'ultima versione stabile (2.4) dal sito ufficiale http://jakarta.apache.org/jmeter/. Per lanciare il programma è necessario eseguire il file jmeter.bat presente nella cartella bin.

Prima di tutto bisogna creare un Test Plan che descrive gli step da seguire per l'esecuzione del

Test. È possibile configurare i seguenti parametri:

Name: ciascun piano di test viene identificato con un nome

User Definned Variables: è possibile associare al piano di test n variabili che possono

essere richiamate all'interno del test;

Run Thread Group consecutively: è possibile stabilire se i thread (utenti virtuali) devono

essere avviati in modalità sequenziale (al termine di un thread viene avviato il successivo)

oppure in modalità parallela (viene lanciato il primo, dopo k secondi viene lanciato il

secondo, dopo 2k secondi il terzo e così via);

Library: è possibile aggiungere delle classi o dei pacchetti jar al classpath.

Nei test effettuati si è provveduto solamente a specificare il Name, che comparirà nel menù ad

albero sulla sinistra, lasciando invariate le altre opzioni.

Page 2: Analisi Prestazionale Applicazione Grails

Cliccando con il tasto destro del mouse sul nome del nostro Test Plan possiamo iniziare ad

aggiungere un Thread Group, l’elemento che conterrà tutti gli altri. Una volta specificato il nome si

va a configurare le seguenti proprietà:

Numero di Threads, che simulano l'accesso contemporaneo di un numero variabile di

utenti

Ramp-up period, il tempo massimo che intercorre dall'avvio del primo thread all'avvio

dell'ultimo

Loop Count, ovvero il numero di volte che deve essere eseguito il test dallo stesso Thread: in

questo caso si può anche simulare un loop infinito, od eventualmente schedulare start e

stop del test.

Una volta aggiunto un Gruppo di Thread, con una procedura analoga, possiamo impostare un

Config Element di tipo HTTPRequestDefault.

Page 3: Analisi Prestazionale Applicazione Grails

Dopo aver specificato il nome dell’ HTTPRequestDefault andremo ad inserire i parametri di

connessione del server su cui gira l’applicazione da testare, cioè l’indirizzo e la porta

Page 4: Analisi Prestazionale Applicazione Grails

A questo punto possiamo aggiungere le HTTPRequest che ci interessano, sempre con il solito

sistema, tasto destro sul Thread Group Add->Sampler->Http Request.

In questa finestra sarà possibile impostare i seguenti parametri principali:

- Name: identificativo della richiesta nel menu;

- Server Name o IP e numero di Porta: nome del server o IP e porta alla quale connettersi; in

tal caso possiamo omettere di specificare questi parametri in quanto in precedenza abbiamo

configurato l’HTTPRequestDefault cui faranno riferimento tutte le nostre Request;

- Method: metodo GET o POST con il quale inviare la richiesta;

- Path: risorsa del server da richiamare;

- Parameters: parametri da passare nella richiesta.

Page 5: Analisi Prestazionale Applicazione Grails

Nel test sulla nostra applicazione abbiamo preso in considerazione il seguente flusso:

1. Accesso ad una pagina di autenticazione.

2. Inserimento delle credenziali di accesso con passaggio di due parametri (username e

password) con forward su una pagina di menu

3. Accesso ad una pagina che presenta una lista di record presenti su DB, nel nostro caso

Proprietari

4. Accesso alla pagina che permette l’inserimento di un nuovo record

5. Inserimento del nuovo record con passaggio di tre parametri (nome, cognome, nazionalita)

con forward su una pagina di riepilogo

6. Nuovo accesso alla pagina con la lista dei record

Per ogni step del flusso è stata creata un HTTPRequest, in modo tale da monitorare ogni

passaggio.

L’ultima operazione da effettuare è la scelta dei Listener, che ci permetteranno di leggere i risultati

del test secondo parametri e visualizzazioni diverse. Nel nostro caso abbiamo utilizzato i seguenti:

- View Result Tree che riassume tutte le richieste e risposte HTTP eseguite durante il test. Per ogni

Thread viene visualizzato l’esito della richiesta con relativa descrizione dettagliata.

- View Result in Table, in cui l’esito delle richieste di ogni Thread è visualizzato in tabella con

minor dettaglio di informazioni.

- Graph Result, che permette di visualizzare il grafico dell’intero test per quanto riguarda

Throughput, Media, Mediana e Deviazione Standard

- Aggregate Graph, che riassume i dati totali e per singola HTTPRequest in una tabella, dando

anche la possibilità di costruire grafici per valutare i tempi di risposta.

Una volta configurati i Listener possiamo far partire il test dalla voce di menu Run -> Start, o

alternativamente la combinazione di tasti CTRL+R. Per arrestare il test Run -> Stop o

alternativamente la combinazione di tasti CTRL+. .

Risultato dei Test

Sono stati compiuti vari test di carico su di un’applicazione Grails variando il numero di utenze, il tempo di Ramp-up degli user e il numero di loop count. Le unità di misura dei test che sono stati compiuti sono le seguenti: Throughput: Request/sec, KB/sec; Tempo: ms(millisecondi);

Page 6: Analisi Prestazionale Applicazione Grails

Il primo test è stato effettuato cambiando il numero di utenze ma mantenendo il tempo di Ramp-up a un secondo e il loop count a 1. Si è notato che da 1 a 10 utenze si ha un incremento del throughput notevole mentre il tempo di esecuzione di ogni thread si è mantenuto costante; mentre da 10 a 140 utenze si mantiene un throughput abbastanza stabile tra le 40 e le 50 request/sec mentre si ha un incremento in maniera costante del tempo di esecuzione di ogni thread (come si può notare dal grafico sottostante). Oltre le 140 utenze abbiamo costatato che alcune request non erano eseguite poiché era lanciata un’eccezione:

“java.net.ConnectException: Connection refused: connect”; la percentuale di questa eccezione aumentava all’aumentare delle utenze che si connettevano.

Figura 1 - Curva che rappresenta il throughput al variare delle utenze con un Ramp-up a un secondo.

Figura 2 - Curva che rappresenta la durata media di ogni ciclo del thread.

In questo test il throughput KB/sec si è mantenuto stabile a circa 270,00 KB/Sec.

Page 7: Analisi Prestazionale Applicazione Grails

Il secondo test effettuato si è modificato il numero di Ramp-up portandolo a 2 secondi mentre si sono lasciati i loops counts a 1 e sono stati variati solamente il numero di utenze. Qui mentre con un’utenza si ha un comportamento costante, con 2 utenze abbiamo un minimo della curva; mentre da 2 a 10 utenze si ha un valore costante del tempo del thread mentre si ha una crescita esponenziale del throughput medio; invece i valori fra 10 e 150 utenze si ha una stabilizzazione del throughput ma una crescita del tempo medio di ogni thread. Una differenza che è stata notata è che il lancio dell’eccezione si è cominciato a costatare oltre le 150 utenze.

Figura 3 – Rapporto throughput/utenze con un Ramp-up a 2 secondi

Figura 4 – Cambiamento del tempo medio di esecuzione del thread.

Anche qui si è notato che il throughput KB/sec rimane costante per tutti i test effettuati a un valore medio di circa 275-280 KB/sec.

Page 8: Analisi Prestazionale Applicazione Grails

Nel terzo test effettuato abbiamo portato il valore di Ramp-up a 5 secondi. Il throughput da 1 a 5 utenze scende molto, mentre da 5 a 50 utenze si ha un nuovo aumento di valore fino a assumere un andamento che si può definire costante fra le 50 e le 200 utenze. Il tempo di esecuzione del thread medio rimane costante in relazione ai due test di prima, da 1 a 10 utenze si ha un tempo di esecuzione costante valorizzato a circa 33 ms, mentre da 50 a 200 utenze si ha un incremento proporzionato. In questo caso l’eccezione viene lanciata oltre le 200 utenze.

Figura 5 – Grafico con Ramp-up di 5 secondi

Figura 6 – Rappresentazione dell’incremento della durata media di ogni thread.

Il throughput medio in KB/sec in questo test si è stabilizzato a circa 280-285 KB/sec.

Page 9: Analisi Prestazionale Applicazione Grails

Nell’ultimo test effettuato si sono incrementati i loop-counts a 10 cicli mentre è stato lasciato costante il valore di Ramp-up. Possiamo notare che il throughput si stabilizza subito, anche con una singola utenza, oltre le 40 request/sec per rimanere costante fino a 150 utenze, valore per cui il server lancia l’eccezione. Mentre il tempo di esecuzione dei thread si incrementa in maniera costante.

Figura 7 – Throughput medio con loop-count impostato a 10

Figura 8 – Tempo medio dell’esecuzione dei thread.

In questo test il throughput rimane stabile fra i 290 e i 300 KB/sec.

Page 10: Analisi Prestazionale Applicazione Grails

Conclusioni

In tutti i test effettuati abbiamo riscontrato delle risposte simili sia per quanto riguarda il throughput,che oltre i 10 accessi si stabilizza intorno alle 50 request al secondo, sia per quanto riguarda il tempo medio di esecuzione del thread. Inoltre il sistema rimane stabile fino alle 150 utenze contemporanee circa: superata questa soglia il web server comincia a lanciare delle eccezioni dovute al sovraccarico di richieste. Dopo aver effettuato diversi test si è constatato che sulle prestazioni dell’applicazione non incide tanto il traffico di rete, quanto la mole di dati presente sul DB. A tal proposito non abbiamo riscontrato rilevanti differenze tra i risultati dei test effettuati su LAN aperta e quelli effettuati su LAN isolata. Al contrario abbiamo assistito ad un calo delle performance man mano che si riempiva il DB: già con tabelle di 1000 record il throughput medio subiva un incremento del 5%. Vista l’incidenza del riempimento delle tabelle sulle prestazioni dell’applicazione, si è provveduto a svuotare il DB ogniqualvolta ci si avvicinava ai 5000 record scritti.

Page 11: Analisi Prestazionale Applicazione Grails

Appendice 1 – Inserimento parametri random nei test In sede di test potrebbe essere conveniente utilizzare dei parametri random in vece di settarli a mano; in questo caso bisognerebbe utilizzare una funzione esterna che generi una stringa casuale. Per implementare questa funzionalità abbiamo sviluppato il seguente metodo: String generateRandomString(int n) { char[] pw = new char[n]; int c = 'A'; int r1 = 0; for (int i=0; i < n; i++) { r1 = (int)(Math.random() * 3); switch(r1) { case 0: c = '0' + (int)(Math.random() * 10); break; case 1: c = 'a' + (int)(Math.random() * 26); break; case 2: c = 'A' + (int)(Math.random() * 26); break; } pw[i] = (char)c; } return new String(pw); } Per poter sfruttare questo metodo bisogna andare a modificare il file BeanShellFunction.bshrc all'interno di jakarta-jmeter->bin, inserendo la funzione da eseguire nel test plan. Il passo successivo è andare a modificare il file jmeter.properties all'interno di jakarta-jmeter->bin abilitando il comando #beanshell.function.init=BeanShellFunction.bshrc (togliendo il carattere # che indica il commento). Ultima cosa da fare è impostare il “Value” nelle singole Http Request a ${__BeanShell(nomefunzione(param))}, dove "nomefunzione" è il nome della funzione definita in jakarta-jmeter->bin, e "param" è la lista di parametri che la funzione vuole in ingresso.

Page 12: Analisi Prestazionale Applicazione Grails

Appendice 2 – Generazione automatica delle risorse da monitorare A proposito del monitoraggio delle risorse abbiamo detto che bisogna configurare singolarmente il path delle HTTPRequest. Se volessimo configurare automaticamente questi path, completando un ciclo di operazioni con la semplice navigazione dell’applicazione da monitorare, è necessario configurare un server proxy, strumento che JMeter mette a disposizione. Andiamo a creare un Recording Controller e un HTTP Proxy Server in questo modo: tasto destro sul ThreadGroup Add -> Logic Controller -> Recording Controller; tasto destro sul Workbench Add -> Non-Test Elements -> HTTP Proxy Server. In assenza di particolari necessità lasciare invariati i settaggi di entrambi. Per completare la procedura andiamo a modificare manualmente i parametri del proxy all’interno del browser che utilizziamo, settando l’indirizzo e la porta. A questo punto possiamo andare sulla finestra dell’ -> HTTP Proxy Server di JMeter e dare il comando di start al nostro proxy. Apriamo il browser e iniziamo a navigare all’interno della nostra operazione: ci accorgeremo che per ogni nostra azione verrà generata una o più HTTPRequest, a seconda delle risorse richiamate. Una volta terminato il ciclo di operazioni che ci interessa testare, non ci resta che scegliere quale HTTPRequest mantenere all’interno del nostro ThreadGroup, in modo tale che quando faremo partire JMeter potremo monitorare solo gli step selezionati.