10. for ((i = 1; i <= 10; i++))
do
echo "---------------------------------"
echo -e "GET /VerySimpleStatelessWebApp/ HTTP/1.0nn" | nc 127.0.0.1 8080
done
10
11. Apache Benchmarking
ab
‟
ab is a tool for benchmarking your Apache
Hypertext Transfer Protocol (HTTP) server. It is
designed to give you an impression of how your
current Apache installation performs.This
especially shows you how many requests per
second your Apache installation is capable of
serving.
http://httpd.apache.org/docs/2.0/programs/ab.html
11
29. ?
Como armazenar o cookie JSESSIONID para utilizar
sempre a mesma sessão do usuário no servidor?
29
30. #fail
Com o ‘ab’, isso não é possível :-(
Mas com um pouco de script, sim ;-)
30
31. Usar netcat e ab para teste de
aplicações web stateless e stateful.
Verifique a limitação com sistemas stateful.
31
32. Apache JMeter
‟
Apache JMeter is a 100% pure Java desktop
application designed to load test functional
behavior and measure performance. It was
originally designed for testing Web Applications
but has since expanded to other test
functions.
http://jakarta.apache.org/jmeter/ 32
36. Definir o conjunto de
threads que executará o
plano de teste
10 threads que devem ser,
todas, iniciadas em 5
segundos
36
37. Definir o tipo de
requisições que serão
feitas pelas threads
criadas Vamos gerar
requisições HTTP
37
38. Endereço do
Servidor HTTP
HTTP Request
Sampler
Porta do
Servidor HTTP
Método de acesso
Nome do contexto ao Servidor HTTP
da aplicação
Sampler para http://localhost:8080/VerySimpleStatelessWebApp
38
39. Iniciar a execução
do plano de teste
Log do servidor
durante a execução
do plano de teste
10 requisições à pagina index.jsp 39
40. Coleta informacões
durante a execução
do plano de teste
Apresenta os
resultados dos testes
em uma árvore
Para ver o resultado dos testes 40
44. JUnit
revisão
• Test Plan
- Base de toda a execução
• Thread Group
- Conjunto de threads responsáveis pela carga
• Sampler
- Tipo de requisições que serão enviadas pelo Thread Group
• Listener
- Coleta informações durante a execução do Test Plan
44
45. Usar JMeter para teste de
aplicações web stateless.
Compreenda seus principais conceitos.
45
53. VerySimpleStatefulWebApp
AutenticacaoServlet
Parâmetro que será
enviado pela requisição
até a Servlet de Servlet de autenticação
Autenticação e então
disponibilizado na
sessão do usuário
53
126. http://localhost:8080/buscador/faces/memoryleak.jsp
javax.faces.ViewState=H4sIAAAAAAAAAJ
javax.faces.ViewState=H4sIAAAAAAAAAJ
j_id_jsp_841419806_1=j_id_jsp_841419806_1
j_id_jsp_841419806_1=criterio1DeBusca
JBoss
O cache de resultados já está com 50008 bytes.
javax.faces.ViewState=H4sIAAAAAAAAAJ
j_id_jsp_841419806_1=j_id_jsp_841419806_1
j_id_jsp_841419806_1=criterio2DeBusca
O cache de resultados já está com 100016 bytes.
120
127. http://localhost:8080/buscador/faces/memoryleak.jsp
javax.faces.ViewState=H4sIAAAAAAAAAJ
javax.faces.ViewState=H4sIAAAAAAAAAJ
j_id_jsp_841419806_1=j_id_jsp_841419806_1
j_id_jsp_841419806_1=criterio1DeBusca
JBoss
O cache de resultados já está com 50008 bytes.
javax.faces.ViewState=H4sIAAAAAAAAAJ
j_id_jsp_841419806_1=j_id_jsp_841419806_1
j_id_jsp_841419806_1=criterio2DeBusca
O cache de resultados já está com 100016 bytes.
120
128. http://localhost:8080/buscador/faces/memoryleak.jsp
javax.faces.ViewState=H4sIAAAAAAAAAJ
javax.faces.ViewState=H4sIAAAAAAAAAJ
j_id_jsp_841419806_1=j_id_jsp_841419806_1
j_id_jsp_841419806_1=criterio1DeBusca
JBoss
O cache de resultados já está com 50008 bytes.
javax.faces.ViewState=H4sIAAAAAAAAAJ
j_id_jsp_841419806_1=j_id_jsp_841419806_1
j_id_jsp_841419806_1=criterio2DeBusca
O cache de resultados já está com 100016 bytes.
120
129. http://localhost:8080/buscador/faces/memoryleak.jsp
javax.faces.ViewState=H4sIAAAAAAAAAJ
variavel=H4sIAAAAAAAAAJ
javax.faces.ViewState=${variavel}
j_id_jsp_841419806_1=j_id_jsp_841419806_1
j_id_jsp_841419806_1=criterio1DeBusca
JBoss
O cache de resultados já está com 50008 bytes.
javax.faces.ViewState=${variavel}
j_id_jsp_841419806_1=j_id_jsp_841419806_1
j_id_jsp_841419806_1=criterio2DeBusca
O cache de resultados já está com 100016 bytes.
121
130. http://localhost:8080/buscador/faces/memoryleak.jsp
javax.faces.ViewState=H4sIAAAAAAAAAJ
variavel=H4sIAAAAAAAAAJ
javax.faces.ViewState=${variavel}
j_id_jsp_841419806_1=j_id_jsp_841419806_1
RegExp j_id_jsp_841419806_1=criterio1DeBusca
Extractor
JBoss
O cache de resultados já está com 50008 bytes.
javax.faces.ViewState=${variavel}
j_id_jsp_841419806_1=j_id_jsp_841419806_1
j_id_jsp_841419806_1=criterio2DeBusca
O cache de resultados já está com 100016 bytes.
121
142. Ao testar JSF,
lembre-se
• Enviar todos os parâmetros requeridos
- Analise o código fonte da página
• Enviar corretamente o campo ViewState
- Utilize o valor gerado pela primeira requisição nas requisições subsequentes
• Gerenciar sessão com HTTP Cookie Manager
- Senão cada requisição de uma mesma thread será vista como um novo usuário
★ Usar RegExp Extrator pra o ViewState;
★ Usar HTTP Proxy Server pra facilitar a criação do Test Plan
131
143. Usar JMeter para teste de
aplicações web stateful e JSF.
Siga passo a passo para sensibilizar-se com o problema
132
173. Lobo Continuous Tuning
‟
Lobo is a tool for tracking performance
designed to register as the performance of
your systems evolve. It is especially useful if
you employ agile practices, because its code
and its architecture evolve.
http://lobo-ct.sourceforge.net 161
174. httperf
‟
Httperf is a tool for measuring web server
performance. It provides a flexible facility
for generating various HTTP workloads
and for measuring server performance.
http://www.hpl.hp.com/research/linux/httperf 162
175. Selenium
‟
Selenium IDE is a Firefox add-on that
records clicks, typing, and other actions to
make a test, which you can play back in
the browser.
http://seleniumhq.org 163
176. http_load
‟
http_load runs multiple http fetches in
parallel, to test the throughput of a web
server. However unlike most such test clients,
it runs in a single process, so it doesn't bog
down the client machine. It can be configured
to do https fetches as well.
http://www.acme.com/software/http_load 164
177. Siege
‟ Siege is an http regression testing and
benchmarking utility. It was designed to let
web developers measure the performance of
their code under duress, to see how it will
stand up to load on the internet.
http://www.joedog.org/index/siege-home 165
178. OpenWebLoad
‟
OpenWebLoad is a tool for load testing web
applications. It aims to be easy to use and
providing near real-time performance
measurements of the application under test.
This is particulary useful when you are doing
optimization as you can see the impact of
your changes almost immediately.
http://openwebload.sourceforge.net 166
179. Grinder
‟
The Grinder is a Java TM
load testing
framework that makes it easy to run a
distributed test using many load injector
machines.
http://grinder.sourceforge.net 167
Teste simples do contexto raiz da aplica&#xE7;&#xE3;o.
Programa&#xE7;&#xE3;o em BASH do teste de carga.
Vejamos agora como trabalhar com aplica&#xE7;&#xF5;es que mant&#xE9;m estado de execu&#xE7;&#xE3;o.
Em nossa aplica&#xE7;&#xE3;o exemplo, h&#xE1; 3 JSPs e 1 Servlet que se interagem da seguinte forma.
Ent&#xE3;o, o usu&#xE1;rio acessa o primeiro JSP pelo browser, preenche seu nome e clica OK, que gera um requisi&#xE7;&#xE3;o para a Servlet que recebe o nome preenchido e armazena-o na sess&#xE3;o do usu&#xE1;rio, devolvendo-lhe um segundo JSP. Neste JSP, o usu&#xE1;rio seleciona algum link, que o leva a um terceiro JSP, que recupera da sess&#xE3;o o nome preenchido na primeira p&#xE1;gina.
O primeiro teste &#xE9; trivial. S&#xF3; criar um Sampler com a URL raiz da aplica&#xE7;&#xE3;o web.
O teste da chamada da Servlet deve simular o envio do par&#xE2;metro pela p&#xE1;gina index.jsp
O teste da p&#xE1;gina funcionalidade1.jsp deve faz&#xEA;-la recuperar o atributo &#x2018;nome&#x2019; da sess&#xE3;o do usu&#xE1;rio.
Perceba que o par&#xE2;metro nome foi recebido pela requisi&#xE7;&#xE3;o e inclu&#xED;do no resultado do JSP.
No primeiro teste, um identificador de sess&#xE3;o de usu&#xE1;rio &#xE9; criado.
Mas no segundo teste, um outro identificador de sess&#xE3;o &#xE9; criado.
E na terceira requisi&#xE7;&#xE3;o, outro JSESSIONID &#xE9; criado! (:-O
Ou seja, n&#xE3;o est&#xE1; havendo o controle desses JSESSIONID para que a sess&#xE3;o do usu&#xE1;rio seja mantida.
Geralmente, JSESSIONIDs s&#xE3;o armazenados em cookie, nativamente suportados em web browsers, mas n&#xE3;o no JMeter.
Usaremos uma simples aplica&#xE7;&#xE3;&#xF5; JSF que simula um sistema de busca.
A cada pesquisa realizada retorna um resultado que &#xE9; armazenado em um cache do servidor.
O cache cresce a cada nova pesquisa, simulando um Memory Leak.
1. Clique no link &#x201C;Memory Leak&#x201D; para apresenta&#xE7;&#xE3;o da p&#xE1;gina memoryleak.jsp
2. Chamada &#xE0; p&#xE1;gina memoryleak.jsp
3. Clique no bot&#xE3;o &#x201C;Buscar&#x201D;
4. Execu&#xE7;&#xE3;o da &#x201C;regra&#x201D; de busca, com persist&#xEA;ncia dos dados recuperados no cache (5)
...
Simula&#xE7;&#xE3;o do clique no link da p&#xE1;gina index.jsp para abertura da p&#xE1;gina memoryleak.jsp onde ser&#xE3;o feitas as pesquisas.
Resultado do teste.
P&#xE1;gina memoryleak.jsp aberta.
Clique no bot&#xE3;o de pesquisa.
Campos HTML gerados por p&#xE1;ginas JSF t&#xEA;m nomeclatura estranha.
Outros campos, tem conte&#xFA;do mais estranho ainda.
Seus valores s&#xE3;o definidos em tempo de execu&#xE7;&#xE3;o, o que torna invi&#xE1;vel a cria&#xE7;&#xE3;o de scripts de testes.
O ideal &#xE9; descobrir esses valores din&#xE2;micos em tempo de execu&#xE7;&#xE3;o e utiliz&#xE1;-los para alimentar as configura&#xE7;&#xF5;es do script de testes.
Ap&#xF3;s a primeira requisi&#xE7;&#xE3;o, capture o valor da express&#xE3;o regular &#x201C;(.+?)&#x201D; retornado e guarde-o na vari&#xE1;vel jsfViewState.
O p&#xF3;s-processamento ocorre ap&#xF3;s a primeira requisi&#xE7;&#xE3;o
Requisi&#xE7;&#xE3;o para teste da funcionalidade de busca. Perceba o conjunto de par&#xE2;metros para simula&#xE7;&#xE3;o do preenchimento do formul&#xE1;rio.
A forma mais f&#xE1;cil de se configurar samplers para o teste de JSF &#xE9; gerando-os automaticamente a partir da dupla Recording Controller e HTTP Proxy Server.
A forma mais f&#xE1;cil de se configurar samplers para o teste de JSF &#xE9; gerando-os automaticamente a partir da dupla Recording Controller e HTTP Proxy Server.
Configure o browser para utilizar o HTTP Proxy Server do JMeter e execute a aplica&#xE7;&#xE3;o pelo navegador.
Ao final da execu&#xE7;&#xE3;o via browser, finalize o HTTP Proxy Server e verifique os Samplers criados sob o Recording Controller.
HTTP Sampler gerado para simula&#xE7;&#xE3;o da funcionalidade de busca, que &#xE9; o que nos mais interessa, pela complexidade dos campos gerados pelo JSF.
Finalizado o teste:
- Remova os samplers que n&#xE3;o forem interessantes para o TestSuite
- Reposicione os samplers interessantes no TestSuite
- Substitua valores fixos por vari&#xE1;veis, se necess&#xE1;rio (e.g. ${jsfViewState})
- Apague Recording Controller e HTTP Proxy Server (opcional)
Cada requisi&#xE7;&#xE3;o est&#xE1; criando uma sess&#xE3;o de usu&#xE1;rio diferente.
Cada requisi&#xE7;&#xE3;o est&#xE1; criando uma sess&#xE3;o de usu&#xE1;rio diferente.
Ap&#xF3;s o HTTP Cookie Manager, a primeira requisi&#xE7;&#xE3;o cria a sess&#xE3;o do usu&#xE1;rio e a segunda reutiliza-a.
Incrementar o n&#xFA;mero de threads para a suite n&#xE3;o provocar&#xE1; o estouro de mem&#xF3;ria.
Cada thread est&#xE1; criando uma nova sess&#xE3;o. Ainda n&#xE3;o &#xE9; isso que queremos. Queremos executar a busca v&#xE1;rias vezes dentro de uma mesma sess&#xE3;o, para que haja o ac&#xFA;mulo de mem&#xF3;ria atrav&#xE9;s do crescimento do cache simulado.
O controlador Loop Controller possibilita a itera&#xE7;&#xE3;o de um conjunto de Samplers.
Para cada requisi&#xE7;&#xE3;o &#xE0; p&#xE1;gina memoryleak.jsp, duas requisi&#xE7;&#xF5;es de busca ser&#xE3;o executadas.
Para melhor legibilidade, demos nomes significativos pra cada Sampler.
- Para cada requisi&#xE7;&#xE3;o &#xE0; p&#xE1;gina de abertura do sistema, duas simula&#xE7;&#xF5;es de busca foram executadas.
- As duas requisi&#xE7;&#xF5;es &#xE0; p&#xE1;gina de abertura foram configuradas no Thread Group. Cada thread criou uma JSESSIONID pr&#xF3;pria. &#xC9; como se fossem dois usu&#xE1;rios distintos.
- As duas simula&#xE7;&#xF5;es de busca foram configuradas no Loop Controller. Ambas as simula&#xE7;&#xF5;es utilizam a mesma sess&#xE3;o da thread.
Cada par de simula&#xE7;&#xE3;o de busca utiliza a sess&#xE3;o de uma thread.
E com isso, conseguimos automatizar a simula&#xE7;&#xE3;o do memory leak.
- Ap&#xF3;s a primeira requisi&#xE7;&#xE3;o, o ViewState &#xE9; criado.
- Nas requisi&#xE7;&#xF5;es subsequentes, o ViewState deve ser reenviado para correta manuten&#xE7;&#xE3;o de estado dos componentes JSF
Ent&#xE3;o, no JSF, funciona assim... (explicar)
S&#xF3; que o valor obtido na primeira resposta deve ser exatamemente o valor utilizado nas reqs posteriores.
Logo, sempre teremos que executar a primeira requisi&#xE7;&#xE3;o, aguardar a resposta, coletar manualmente o valor gerado e inform&#xE1;-los nos samplers seguintes, o que acaba gerando um grande desperd&#xED;cio de tempo no processo de testes.
Ent&#xE3;o, no JSF, funciona assim... (explicar)
S&#xF3; que o valor obtido na primeira resposta deve ser exatamemente o valor utilizado nas reqs posteriores.
Logo, sempre teremos que executar a primeira requisi&#xE7;&#xE3;o, aguardar a resposta, coletar manualmente o valor gerado e inform&#xE1;-los nos samplers seguintes, o que acaba gerando um grande desperd&#xED;cio de tempo no processo de testes.
Ent&#xE3;o, no JSF, funciona assim... (explicar)
S&#xF3; que o valor obtido na primeira resposta deve ser exatamemente o valor utilizado nas reqs posteriores.
Logo, sempre teremos que executar a primeira requisi&#xE7;&#xE3;o, aguardar a resposta, coletar manualmente o valor gerado e inform&#xE1;-los nos samplers seguintes, o que acaba gerando um grande desperd&#xED;cio de tempo no processo de testes.
Ent&#xE3;o, no JSF, funciona assim... (explicar)
S&#xF3; que o valor obtido na primeira resposta deve ser exatamemente o valor utilizado nas reqs posteriores.
Logo, sempre teremos que executar a primeira requisi&#xE7;&#xE3;o, aguardar a resposta, coletar manualmente o valor gerado e inform&#xE1;-los nos samplers seguintes, o que acaba gerando um grande desperd&#xED;cio de tempo no processo de testes.
Ent&#xE3;o, no JSF, funciona assim... (explicar)
S&#xF3; que o valor obtido na primeira resposta deve ser exatamemente o valor utilizado nas reqs posteriores.
Logo, sempre teremos que executar a primeira requisi&#xE7;&#xE3;o, aguardar a resposta, coletar manualmente o valor gerado e inform&#xE1;-los nos samplers seguintes, o que acaba gerando um grande desperd&#xED;cio de tempo no processo de testes.
- Pra ficar mais din&#xE2;mico, a gente captura o valor em tempo de execu&#xE7;&#xE3;o, logo ap&#xF3;s a primeira requisi&#xE7;&#xE3;o, guarda-o em uma vari&#xE1;vel e o reutiliza nas pr&#xF3;ximas requisi&#xE7;&#xF5;es.
Como eu soube que esses eram os dados a serem enviados pelo JMeter?
Ora, eu entrei na p&#xE1;gina...
...e vi o c&#xF3;digo fonte.
Na pr&#xE1;tica, isso funciona da seguinte forma:
Na verdade, este proxy &#xE9; um elemento do JMeter e tem o nome de HTTP Proxy Server.
1a parte: buscador.war
2a parte: aplica&#xE7;&#xE3;o real
P&#xE1;gina principal do Tomcat cont&#xE9;m a mensagem &#x201C;Thanks for using Tomcat!&#x201D;
- Deseja-se que toda resposta de HTTP Request contenha a string &#x201C;Thanks for using Tomcoat&#x201D;
- A string n&#xE3;o &#xE9; encontrada na resposta e o teste falha.
- Deseja-se que toda resposta de HTTP Request contenha a string &#x201C;Thanks for using Tomcat&#x201D;
- Teste bem sucedido!
[ToDo] Detalhar?
Chega uma hora que o jmeter n&#xE3;o consegue gerar a carga de requisi&#xE7;&#xF5;es desejada.