Cosas que añadir Cosas que añadir

«Atrás

Usando JMeter para el estrés Web

Vamos a dar aquí una guía rápida para realizar pruebas de estrés contra aplicaciones y servidores Web, y una serie de consejos fruto de la experiencia y, como no, de haber cumplido el principio RTFM para el caso de JMeter, en aquellos gratos momentos de uso de la herramienta.

Introduccion

Añadir Grupo de Hilos

Configurar el Plan para las peticiones Web

Configuración del Listener

Recogiendo los samplers HTTP: el proxy de JMeter y nuestro navegador

Filtrar las peticiones recogidas

Ejecución del Test

Leer los resultados del Test de JMeter

Summary Report' e 'Informe Agregado'

Árbol de Resultados

Resumen

 

 

Introducción

La interfaz gráfica de JMeter es un tanto minimalista:

JMeter recién arrancado

Su uso se basa en el concepto de Plan de Pruebas (Test Plan) , que es el conjunto de acciones que JMeter realizará cuando la prueba se ejecute.

El Plan de Pruebas puede estar formado por varios tipos de items: Grupo/s de Hilos, controladores lógicos, listeners, elementos de configuración, etcétera. Vamos a usar aquí los básicos para un Plan de Pruebas para una aplicación web.

Añadir Grupo de Hilos

El Grupo de Hilos (Thread Group) es el punto de entrada de los tests, ya que representa a los usuarios de la aplicación; por eso, es necesario que haya al menos uno en todo plan de pruebas. Cada uno de los hilos del grupo ejecutará el plan de forma completamente independiente a los demás hilos,  y la mayoría del resto de elementos de un Plan de Pruebas, deben estar incluidos en el Grupo de Hilos.

Grupo de hilos en el Plan de Pruebas

Notas de la GUI: Para añadir elementos al Plan de Pruebas se utiliza el menú contextual (botón derecho) sobre el árbol de la izquierda

En el Grupo de Hilos se configura el número (cantidad de usuarios), el período de subida y el contador del bucle. El primero se explica por sí sólo.

El Período de Subida (Ramp-up period) indica cuantos segundos se tardará en alcanzar el número máximo de usuarios: si tenemos 10 hilos y establecemos este período en 100 segundos, JMeter tardará 100 segundos en tener activos los 10 hilos; esto es, arrancará uno cada 10 segundos.  Como pista general, y traduciendo del manual de JMeter: 

"El periodo de subida debe ser suficientemente grande para evitar una carga excesiva en el inicio de la prueba, y lo suficientemente corto para que los últimos hilos arranquen antes de que los primeros terminen (a no ser que sea eso precisamente lo que se busca)"

El contador del bucle representa el número de veces que cada hilo ejecutará la prueba.

También se pueden ejecutar los Grupos de Hilos en diferido con el Planificador (Scheduler). Esto es muy útil, por ejemplo, si tenemos un Plan de Pruebas con un grupo de hilos en ejecución continua (los usuarios públicos que visitan la web) y otro grupo que representa, por ejemplo, los momentos de mayor uso por parte de los usuarios internos, y que arrancamos de forma independiente al primero.

Configurar el Plan para las peticiones web

Los elementos que se ejecutan al arrancar un plan de pruebas son los denominados Controladores (Controllers). Los más importantes son los  Muestreadores (Sampler): Para peticiones FTP, HTTP, JDBC, LDAP,  Objetos Java y servicios web y otros. Son los que indican a JMeter qué enviar al servidor, y mediante qué protocolo hacerlo

Como podeis suponer, nos centramos en los elementos de Plan de Pruebas referentes a HTTP. Además de los controladores, para el estrés web necesitaremos algún elemento de configuración y algún listener. Como mínimo, para casi cualquier aplicación web, necesitaremos:

  • Un conjunto de samplers HTTP: las peticiones a enviar al servidor. Más adelante aprenderemos a obtenerlas de forma sencilla
  • Un Gestor de Cookies HTTP: Es un 'Elemento de Configuración' que permite que cada hilo (usuario) tenga acceso a las cookies enviadas por el servidor. Es la manera de que el Plan de Pruebas pueda mantener el estado de la aplicación  web (la sesión HTTP).
  • Uno o varios Listener que muestren los datos estadísticos recogidos.

Con todo lo dicho, añadimos a nuestro Plan de Pruebas un Gestor de Cookies (botón secundario sobre el Grupo de hilos--> Añadir Elemento de Configuración --> Gestor de Cookies HTTP ), y un 'Escritor de datos simple' (botón secundario sobre el Grupo de hilos--> Añadir Listener --> Escritor de datos simple):

 

Plan de Pruebas con Gestor de Cookies y Listener

Notas de la GUI: Los cambios que hacemos en la parte derecha del panel se guardan automáticamente en el Plan de Pruebas. Pero aparte de ello es conveniente guardar el Plan de Pruebas al completo (en un fichero .jmx), cosa que puede hacerse con el menu contextual (botón secundario) sobre el nodo del Plan de pruebas en el árbol de la izquierda.

Configuración del Listener

El Listener es el que recoge los datos de tiempo de respuesta, número de errores y otros datos estadísticos de la ejecución de un Plan de Pruebas. Existen muchos tipos distintos. En el manual de JMeter nos avisan de que todos los listener guardan los mismos datos, pero los visualizan de forma distinta.

Los datos que recogen los listeners, y el formato en el que lo recogen, es común a los diferentes tipos de Listener. Normalmente sólo es necesario añadir uno para recoger los datos, pero pueden añadirse más de uno que recoja los datos de distinta forma, aunque sean siempre los mismos. Por ello es conveniente configurarlos para atender a las necesidades de nuestra Prueba: si tenemos muchas muestras de petición HTTP necesitamos adelgazar al máximo el fichero de resultados. Primero estableceremos un fichero de destino para los resultados, desde el botón 'Navegar' (ver captura anterior): los formatos son .jtl (XML propio de JMeter) y CSV.

Notas de la GUI: Al poner un nombre de fichero JMeter os mostrará un mensaje de error avisando de que no ha podido cargar el archivo. No pasa nada: en cuanto tenga que escribir datos (durante la ejecución de Text) JMeter creará el fichero.

Tras tener el fichero de destino desde el botón 'Configurar' del Listener (ver captura anterior) accedemos a las propiedades del Listener:

Opciones de configuración de un Listener

Existen parámetros que sólo se aplican si guardamos los resultados en formato XML, no CSV (esta información se ha perdido en la traducción al español de JMeter. Si elegís el idioma inglés en este diálogo aparece entre paréntesis si el parámetro afecta sólo a CSV o a XML). Tened en cuenta que en formato CSV no se pueden almacenar nada que lleve saltos de línea. Los datos de respuesta de la web  (Save Response Data), por ejemplo, no pueden ser guardados en CSV

Algunos de estos parámetros tienen mucha influencia en el tamaño del fichero de resultados que obtendremos; para empezar si es XML o no: guardado en un formato estilo CSV el fichero se reduce bastante.  Dependiendo de los objetivos de nuestro Plan de Pruebas, nos interesará recoger cosas distintas. A lo largo de muy distintas pruebas yo lo que he encontrado siempre útil es utilizar un 'Escritor de Datos Simple' desactivando el uso de XML. Los ficheros generados pueden ser abiertos luego desde distintos Listener para visualizar un mismo conjunto de estadísticas de distinta forma. Pero si queremos observar los datos que ha devuelto el servidor (y no sólo sus códigos de éxito o error) necesitamos el formato XML.

Recogiendo los samplers HTTP: el proxy de JMeter y nuestro navegador

Tenemos los usuarios, tenemos configurados los datos a recoger y donde. Nos falta los más importante: las peticiones para el servidor. Los controladores de Petición HTTP pueden añadirse uno a uno, pero es muy tedioso cuando queremos capturar, por ejemplo, diez minutos de uso de la aplicación web que generen 200 peticiones HTTP. Para ello JMeter cuenta con un elemento que mediante un patrón Proxy puede capturar el tráfico entre un navegador y el servidor web. Sobre Banco de Trabajo --> botón secundario --> Añadir --> Elementos NoDeprueba --> Servidor Proxy HTTP

 

La idea consiste en que configuraremos un navegador para que use de proxy la dirección del proxy de JMeter: [nombre-maquina]:8080. (Es preferible usar el nombre de máquina en lugar de 'localhost' dado que no siempre los navegadores dejan usar la dirección de loopback como proxy).

No os olvideis de arrancar y parar el proxy cuando cambiemos algo en su configuración. ¡¡Y las preferencias del navegador para que use a JMeter de proxy!!

De la configuración del proxy destacamos dos cosas: el puerto (8080 por defecto) y la agrupación de los datos de la muestra: Controlador Objetivo y Agrupación. Ambos valores se refieren a cómo se van a agrupar las muestras (las peticiones HTTP) en el árbol del plan de pruebas. A mi siempre me ha sido útil seleccionar en el desplegable de 'Agrupación' la opción 'Poner cada grupo en un nuevo controlador': esta forma de agrupar peticiones, intenta organizar el conjunto de muestras distinguiendo entre los distintos 'clicks' en el navegador; como se puede suponer la distinción entre un click y otro la hace simplemente por el tiempo transcurrido entre una petición y otra. Las aplicaciones asíncronas (AJAX) registrarán las peticiones de forma asíncrona; pero eso no debe ser problema: la asincronía de peticiones no debe dar problemas si nuestra aplicación se comunica así con el servidor.

Esto he capturado con las opciones por defecto del proxy:

 

Las peticiones han sido :

  • Raíz de la web http://rafaeska.es
  • Click en sección 'Algo que añadir'
  • Click en sección 'Android'

Como veis, se han creado varios controladores HTTP, unos para direcciones dinámicas y otros para direcciones estáticas.

Ahora vamos a establecer alguna agrupación para las peticiones para que queden más legibles y para poder identificar los distintos 'clicks' del usuario: en el combo de 'Agrupación' dentro de la configuración del proxy de JMeter seleccionamos 'Poner cada grupo en un nuevo controlador'. Borro las peticiones registradas hasta ahora (sobre los nodos del árbol) y reinicio el proxy de JMeter.

Ahora una navegación idéntica a la anterior queda agrupada así:

 

Filtrar las peticiones recogidas

Dependiendo de los objetivos de nuestra Prueba es habitual necesitar no incluir en nuestras peticiones ciertos recursos que el navegador solicita al servidor. Por ejemplo, si nuestra intención es comprobar el comportamiento de una aplicación web con altas cargas de trabajo o mucha cantidad de datos es posible que lo que nos interese son las peticiones dinámicas, las que generan carga de proceso. Esto es habitual cuando probamos en entornos de pruebas, con capacidades de ancho de banda menores que los de los entornos donde finálmente se desplegará la aplicación.

Por otra parte, si queremos tiempos de respuesta más fieles al entorno real, no deberíamos filtrar ninguna petición.

En cualquier caso, desde la configuración del Proxy HTTP, podemos elegir qué peticiones registrar y cuales no basándonos en las URLs y ayudándonos de las bénditas/malditas expresiones regulares.

En mi caso no me interesa incluir las peticiones a imágenes. En el campo 'URL Patrones a excluir'  de la configuración del Proxy HTTP pongo

 .*\.png
.*\.ico

Con ello, evito PNGs e ICOs. La misma recogida de peticiones anterior ahora queda así:

Con las peticiones agrupadas en tres controladores (los 3 clicks del usuario) y sin imágenes PNG ni ICO.

 

Ejecución del Test

Nuestro Plan de Pruebas ya está preparado. Mi árbol muestra este aspecto:


La ejecución de la prueba se arranca desde el menú 'Lanzar' y la única indicación de que se está ejecutando es un pequeño cuadradito en verde en la esquina superior derecha de la interfaz

Cuando se apaga este piloto verde, la prueba ha terminado

Nota de la GUI: El pequeño piloto verde tiene a su lado izquierdo el número de hilos en ejecución sobre el total de hilos (2 de un total de 10)

Leer los resultados del test de JMeter

Es el momento de hacer lo más difícil: interpretar los resultados. Con los diferentes listener puedo leer un mismo conjunto de datos. Vamos a añadirlos ahora al Plan de Pruebas, con el único fin de abrir el fichero de resultados y visualizar los resultados de diferentes maneras

'Summary Report' e 'Informe Agregado'

La única diferencia entre ambos es que el Informe Agregado calcula el Percentil 90 de la muestra y el Summary Report no. Es más ligero en memoria el último, así que usad preferentemente el 'Summary Report'.

¿Qué significan sus campos?

Tenemos una tabla con una fila para cada petición realizada. Observad que las peticiones a '/combo' se han repetido 30 veces (columna Muestras): esto es porque existían 3 muestras de peticiones a esa URL en diferentes momentos de la Prueba. Aquí salen agrupadas.

Los valores están calculados tomando el tiempo total que ha tardado la prueba (la ejecución de mis 10 usuarios), por lo tanto, cuanto más muestras haya más tiempo total de ejecución; influye en cada línea de la tabla. Para cada línea (petición) tenemos 

  • el máximo de tiempo invertido por una petición (columna Max).
  • el mínimo de tiempo invertido por una petición (columna Min).
  • la media de tiempo invertido por una petición (columna Media).
  • la mediana de tiempo invertido por una petición: significa que el 50% de las muestras tardaron menos del valor reflejado.
  • El tanto por ciento de respuestas con error.
  • El rendimiento (thoughput): número de peticiones procesadas en una unidad de tiempo, que puede ser segundos, minutos y horas.
  • El rendimiento en Kb/segundo: igual que la anterior pero con cantidad de datos en lugar de peticiones

Podemos decir, por ejemplo, que el servidor es capaz de responder a 1,6 peticiones por segundo a la página raíz de la web (primera muestra), o que la petición a '/html/portlet/blogs/css/main.jsp'   es la que más tarda en procesarse de media.

Una versión extendida del 'Informe Agregado' es el 'Aggregate Graph', que muestra los mismos datos que aquel, pero permitiendo generar gráficos de barras de las diferentes columnas (media, máximo, mínimo...). Los gráficos se pueden guardar, para incluir en el bonito informe para el jefe. Observad que he necesitado aumentar el 'Height' por defecto del gráfico:

(Pulsar para ampliar)

Para estos mismos datos existen otros listeners para visualizar los resultados en gráficos de distintos tipos, como el 'Gráfico de Resultados' que muestra en un sólo gráfico los valores estadísticos recogidos relacionados con el número de muestras: cuanto mayor sea el número de muestras (peticiones) más representativos serán los datos de este gráfico.

Árbol de Resultados

Es un listener muy útil, sobre todo cuando nuestro objetivo principal es comprobar el funcionamiento de una aplicación concreta, más que toda una infraestructura web.

El  'Árbol de Resultados'  permite visualizar los datos de petición y respuesta de cada una de las muestras individuales (140 en total, en nuestro ejemplo). Es muy utilizado cuando estamos depurando el comportamiento de la Prueba : ¿Por qué no se dan de alta los datos en la base de datos? ¿Por qué la petición que sé que tarda más me responde tan rápido en la Prueba?. A primera vista parece que la respuesta más habitual a estas preguntas está en que hay mensajes de error (los entrañables HTTP 50x) en las respuestas del servidor.  Pero para depurar esto lo que necesito es ver qué errores se han producido, porqué se han producido y con qué peticiones.

Como avisé antes, para esto necesitaremos que nuestro Listener (nos sirve el Escritor de Datos Simple) guarde las respuestas del servidor, y para poder hacer esto, tiene que almacenarse en formato XML y seleccionar las opciones de configuración adecuadas.

Es conveniente, para la depuración del funcionamiento de la Prueba, y para depurar el funcionamiento de una aplicación web, conservar las cabeceras de respuesta HTTP.

Al configurar en mi Prueba el listener de esta forma, mis tres insignificantes clicks con 10 usuarios han generado un fichero de resultados de 5,6 MB, por lo que usad con cuidado con el fichero de resultados en esta recogida de datos.

El Árbol de resultados permite previsualizar la respuesta del servidor, formateandola de diferentes formas: XML, HTML y JSON las más relevantes. Además podemos buscar literales y Expresiones Regulares en la respuesta:

(Pulsar para ampliar)

Resumen

Hemos configurado un Plan de Pruebas con los usuarios de la prueba, el Listener para recoger los datos, y las peticiones generadas por nuestro navegador contra el Proxy HTTP de JMeter. Hemos ejecutado la prueba y hemos observado sus resultados con diferentes visualizadores (Listerner).

Tenemos un punto de partida básico para empezar a hacer pruebas, y una pequeña experiencia con JMeter que nos va a servir para el próximo artículo. Unas Buenas Prácticas para estrés web con JMeter.

Espero que os sirva de algo

Comentarios
Añadir comentario

Estupendo! Estresaré alguna cosilla este fin de semana.

Publicado el día 29/11/10 12:06.

Responder Arriba
Hola .. puedo usar parte de tu información, para un trabajo mio, haciendo mencion de tu autoria???

Publicado el día 17/12/12 17:12.

Responder Arriba
muy útil. Gracias!

Publicado el día 24/01/13 16:29.

Responder Arriba
Para el comentario de 17/12/2013: depende de para qué sea el trabajo. Si es con fines educativos, sí. Si quieres cuéntamelo en rafaeska EN gmail.com

Publicado el día 24/02/13 11:53 en respuesta a .

Responder Arriba
hola! me gustaría saber tu opinón sobre cuál es el mejor modo para ver la respuesta del serviodor en json y poder comprobar que no llega a null?¿
gracias!

Publicado el día 31/10/13 10:29 en respuesta a Rafa Eska.

Responder Arriba
si puedes hacerlo es libre esto

Publicado el día 10/03/14 15:31 en respuesta a .

Responder Arriba
Hola. contaras con un manual donde pueda revisar como grabar los flujos con el jmeter

Publicado el día 2/06/17 18:22.

Responder Arriba