RESTful Stress: misurare le performance di un servizio REST

Nel post di qualche settimana fa (lo potete trovare a questo link) abbiamo fatto una rapida introduzione al tema delle misurazioni delle prestazioni di una piattaforma applicativa fortemente basata su REST. Il tema è estremamente complesso, e le quattro idee che ho "buttato giù" sono solo la superficie di un mondo vastissimo ed articolato.

Al mio primo approccio con questo argomento - non lo nego - mi sono trovato parecchio spiazzato. Sono sempre stato abituato a "calcoli insindacabili" e certezze; ma tutto questo richiede una buona dose di analisi dei comportamenti e di...speranza.

Dico questo per un motivo molto semplice: rispondere alla domanda "quanti utenti l'ora è in grado di supportare la mia applicazione?", non è così banale. Vuol dire prima misurare tutto il misurabile, e poi dover fare i conti con la variabile più imprevedibile con cui un professionista dell'IT deve fare i conti: il comportamento dell'utente medio.

Se per la "variabile utente" non potete fare altro che osservare e ipotizzare che venga fatto un uso normale del vostro sistema, per le misurazioni - forse - può darvi una mano una piccola Chrome Application (originariamente detta "Chrome Packaged App") a cui ho iniziato a lavorare nel 2013 e che ho recentemente reingegnerizzato: RESTful Stress.

In breve. Si tratta di uno strumento in grado di simulare le chiamate HTTP verso una piattaforma di servizi REST, usando il componente XHR (XMLHttpRequest) del browser. In parole povere, fa esattamente quello che farebbe uno script jQuery client-side (una cosa del tipo "$.ajax(...)" ecc.) che invia e riceve dati da un server remoto.

Mi chiederete: "E dove sta la differenza?". È in grado di iterare la vostra chiamata HTTP (una o più chiamate) numerose volte, campionando l'orario di inizio, di fine, la durata, lo stato e il contenuto della response. Una volta rilevate le informazioni è in grado di produrre un feedback relativo alle performance che può essere facilmente e rapidamente interpretato.

Una volta installato RESTful Stress (versione 1.2.0) dal Chrome Web Store (a questo indirizzo), lo avviate, e vi troverete davanti a questa prima pagina:


Non complichiamo subito le cose: tralasciamo la modalità di misurazione presente in alto a sinistra (quella con " Atom", "Massive" e "Scenario", per intenderci) prendendo in considerazione il default "Atom". Come è possibile vedere c'è tutto l'occorrente per definite le specifiche di una chiamata HTTP:
  • Metodo HTTP, o "Verb": GET, POST, PUT, DELETE i più usati
  • Headers, in formato JSON, per maggiore flessibilità
  • Body, anche questo in JSON visto che siamo su REST
  • With credentials, ovvero forzando il passaggio di cookie autorizzativi ottenuti in una precedente iterazione
  • URL di destinazione (beh....ovviamente)
Nel box posto in alto alla view in questione, sono presenti le specifiche dell'iterazione di RESTful Stress: numero di cicli di esecuzione ("iterations"), intervallo tra una iterazione e la successiva ("delay"), "timeout" oltre il quale una chiamata HTTP è considerata fallita, e numero di iterazioni considerate "warmup" del sistema.

Solo una piccola parentesi su questa ultima specifica ("warmup", appunto), per sottolineare come - sovente - quando si invoca un servizio web (di qualunque genere) è normale che le prime chiamate siano particolarmente lente rispetto alle successive. In particolare, in ambiente .NET, IIS ha un comportamento tale che porta ad inizializzare alcuni componenti applicativi solo alla prima esecuzione degli stessi. E' così quindi che, durante i primi cicli di esecuzione, la nostra applicazione sembra essere particolarmente letargica: in realtà è sono in fase di "risveglio" prima di prendere il giusto ritmo. E' un diesel, se vogliamo...

A fondo pagina c'è tutto l'occorrente per non perdere le nostre impostazioni: "Store settings", che permetterà di salvare le specifiche nella storage area di RESTFul Stress (unitamente ad un nome mnemonico), e due comodi pulsanti per scaricare gli stessi settings su un file del vostro computer locale ("Download"), e per poi ripristinarli in seguito ("Upload").

Una volta impostati i dettagli, non resta altro da fare che cliccare il pulsante "Play", ed attendere che il tool faccia il suo sporco lavoro, eventualmente fermandolo con "Stop" (attenzione: bisognerà attendere la fine dell'esecuzione della request per avere l'arresto effettivo) o "Reset".

Completata l'esecuzione dei cicli (o durante il progress...e chi ce lo vieta?) possiamo analizzare la "history" delle chiamate; ciascun elemento è caratterizzato da :
  • codice di Status HTTP recuperato dal server: 200, 401, 404, ecc...(eventuali status codes con valore "0" rappresentano sempre una request mai effettuata)
  • orario di inizio della request verso il server
  • durata in millisecondi, ovvero il tempo tra l'invio della request e la ricezione della corrispondente response
  • lunghezza in bytes del contenuto della risposta
...e un comodo pulsante per visualizzare il contenuto del body della response stessa.


Utilizzando gli appositi "commands" localizzati nella parte alta della pagina, per non perdere i risultati del proprio lavoro, è possibile estrarre tutte le informazioni raccolte in formato JSON ("Download"), ricaricarle in RESTFul Stress per una consultazione successiva ("Upload") oppure produrre il più classico dei file CSV con un subset dei dati in elenco.

La scelta di JSON come formato di esportazione dei risultati di esecuzione non è casuale: spesso mi sono trovato a dover utilizzare gli stessi dati in altre applicazioni JavaScript-based (es. NodeJs o AngularJs) o .NET (usando il meraviglioso componente Json.NET): quale miglior formato per manipolare dati privi di uno schema predefinito?

La pagina "Chart" mostra in formato grafico l'andamento delle iterazioni sul servizio: in un secondo è possibile evidenziare eventuali deterioramenti della performance della piattaforma (magari per risorse che non vengono rilasciate correttamente), picchi di utilizzo, eventuali response con codici di errori (rappresentati con il colore rosso), e - ovviamente - le iterazioni che abbiamo battezzato nella pagina di settings come "warmup" del sistema (colore azzurro); queste ultime - come detto - vanno correttamente pesate nelle nostre considerazioni, essendo figlie di una fase di inizializzazione del sistema, e che quindi non rappresentano la reattività dello stesso a regime.


Il grafico è corredato di alcune misurazioni "grossolane" delle tempistiche: valori medi che danno un'idea della reattività della piattaforma, e permettono di iniziare a fare qualche considerazione in più rispetto i concetti espressi nel precedente post.

Facciamo un salto in avanti, e arriviamo alla sezione che permette di ripristinare i settings salvati nella prima pagina di RESTful Stress. Mi sembra una grossa perdita di tempo illustrarvi il suo contenuto: l'immagine parla da sola, e con essa il funzionamento di questa feature.


No, non mi sono dimenticato della pagina "Performance": è senza dubbio la parte più interessante e quella per cui avrete probabilmente iniziato a leggere questo post. Essa porta con se molte considerazioni, calcoli, manipolazioni e spiegazioni che richiedono il loro tempo...e non quattro concetti buttati sul piatto in malo modo. Me li custodisco come "succosi" argomenti per il prossimo articolo...

Buone ferie a tutti...
M.

Commenti

Post popolari in questo blog

Restore di un database SQL Server in un container Docker

Cancellazione fisica vs cancellazione logica dei dati

WCF RESTful service: esposizione del servizio