Ejecución de las Pruebas con JMeter

Aquí viene el gran punto: la ejecución de las pruebas. Este es el paso más importante y quizá complejo del proceso, no se trata de lanzarse a ejecutar el script contra la aplicación, sino de conocerla, conocer los servidores, la infraestructura y determinar realmente si hay problemas y cuales son estos. Los objetivos de este paso son:

  • Establecer una línea base de tiempos. Esto es para compara el tiempo de respuesta de una ejecución con el tiempo presentado ante peticiones concurrentes.
  • Determinar si el incremento en los tiempos de respuesta se debe a falta de optimización o al degradamiento de los recursos físicos.
  • Al igual que unas pruebas funcionales, las pruebas de carga deben tener un libreto o serie de pasos exactos a seguir.
  • Determinar antes de la ejecución, qué datos se van a recoger, en que formato y como será su almacenamiento.
  • Si las pruebas se realizan en un ambiente diferente al de producción, los resultados deben poder extrapolarse para saber que sucedería en el ambiente real. Por esto el ambiente de las pruebas debe ser comparable al de producción en tecnología y en capacidad pudiéndose expresar en términos como 1/3 del ambiente de producción, 1/2, 1/4, 1/10 o algo similar.

Algunas recomendaciones para cualquier ejecución.

  • Al igual que objetivos y resultados, defina los escenarios a probar antes de comenzar al proceso. Realice un análisis de su arquitectura y defina escenarios que cubran el mayor número de componentes posibles y no deje ningún componente crítico sin probar.
  • Para establecer la línea base de tiempos de respuesta, haga siempre una primera ejecución con varias peticiones en serie.
  • Procure no lanzar ráfagas de peticiones con un sólo ciclo, por ejemplo, 100 usuarios virtuales y un sólo ciclo. Con estas ejecuciones los tiempos no siempre son reales porque la misma herramienta toma su tiempo antes de arrancar el número de hilos solicitados. Procure más bien ciclos cuando use muchos usuarios concurrentes, por ejemplo 100 virtuales y 3 ciclos.
  • Sea cuidadoso y metódico para tomar y almacenar datos. Una confusión o malinterpretación lo pueden llevar a tareas complejas que no solucionarán ningún problema.
  • Cuando optimice, en lo posible haga un cambio al tiempo y pruebe. Esto le permitirá medir el impacto real de las mejoras o descubrir que ciertas "optimizaciones" no son tal.
  • Mantenga los generadores de carga y otras aplicaciones de alto consumo de recursos aislados de la aplicación que está probando. Aún en ambientes de desarrollo esta es una condición fundamental para no confundir el consumo de recursos de la aplicación con el consumo de recursos de las otras herramientas. (Como este taller es un ejercicio de aprendizaje, esta condición no es estrictamente necesaria).

Pasos previos a la ejecución

1. Prepare adecuadamente una hoja de cálculo o algún elemento en el que pueda tomando nota de las ejecuciones de las pruebas.
Ejemplo de hoja de cálculo para tomar datos durante la ejecución:

Ejecución de las Pruebas

2. Cierre todas las aplicaciones que puedan interferir con el proceso. Deje abiertas únicamente las que son estrictamente necesarias. En este caso, si está ejecutando todo localmente, deje abierto JMeter y Tomcat. Pero como mencioné anteriormente, en una prueba real, no puede hacer que la herramienta generadora de carga comparta recursos con la aplicación.

Ejecución de las pruebas.

Una ejecución de pruebas de carga debe iniciar con peticiones en serie para conocer los tiempos de la aplicación cuando no está sometida a carga. Después en cada siguiente ejecución incremente la exigencia aumentando el número de usuarios virtuales y durante cada incremento tome nota de los tiempos y consumo de recursos para compare y genere un gráfico de tendencia que le permitirá reconocer fácilmente si la aplicación escala o no; estos datos también le permitirán obtener datos sobre el consumo de recursos, especialmente de memoria.

  1. Iniciar el contenedor con la versión base de la aplicación.
  2. Cambie el archivo de destino de datos por Prueba01.Ejecucion01.1x20.txt
  3. Ejecutar el script con 1 usuario virtual y un ciclo de 20 iteraciones.
  4. Almacenar los datos generados como versión base y extraer:
    • Tiempos de respuesta por URL.
    • Consumo de memoria HEAP.
  5. Reinicie el servidor.
  6. Cambie el archivo de destino de datos por Prueba01.Ejecucion02.5x20.txt
  7. Ejecute el script con 5 usuarios virtuales y un ciclo de 20 iteraciones.
  8. Almacene los datos y reinicie el contenedor.
  9. Cambie el archivo de destino de datos por Prueba01.Ejecucion03.10x10.txt
  10. Ejecute el script con 10 usuarios virtuales y un ciclo de 10 iteraciones.
  11. Almacene los datos y reinicie el contenedor.
  12. Cambie el archivo de destino de datos por Prueba01.Ejecucion04.20x5.txt
  13. Ejecute el script con 20 usuarios virtuales y un ciclo de 5 iteraciones.
  14. Almacene los datos y reinicie el contenedor.
  15. Cambie el archivo de destino de datos por Prueba01.Ejecucion05.25x4.txt
  16. Ejecute el script con 25 usuarios virtuales y un ciclo de 4 iteraciones.
  17. Almacene los datos y reinicie el contenedor.
  18. Cambie el archivo de destino de datos por Prueba01.Ejecucion06.50x2.txt
  19. Ejecute el script con 50 usuarios virtuales y un ciclo de 2 iteraciones.
  20. Almacene los datos y reinicie el contenedor.

No siempre es posible ejecutar todo el libreto como está planeado, a veces errores tempranos en la aplicación o la infraestructura hacen que la ejecución falle desde la primera o segunda prueba. Por esta y muchas más razones, el proceso de pruebas y optimización es iterativo y cuando aparece un error bloqueante, es decir, que no deja que las pruebas continúen, se procede a almacenar los resultados y realizar una o varias optimizaciones necesarias para continuar y se repite el libreto de pruebas. Este proceso se repite hasta cumplir con las metas planteadas antes de iniciar el proceso o hasta que definitivamente encontremos los límites de la arquitectura.

Esta naturaleza iterativa, exige que el proceso de planeación de las pruebas sea muy estricto y claro en cuanto a las metas y el alcance propuesto.


Prueba 1 Ejecución 1.
Esta primera ejecución será con 1 usuario virtual y un ciclo de 20 iteraciones.

1. En el script de JMeter vaya al nodo Grupo de Hilos y en el campo Contador del bucle ingrese el número de iteraciones, es decir, 20.

Ejecución de las Pruebas

2. Seleccione el nodo Ver Resultados en Árbol e ingrese la carpeta y nombre del archivo de logs. En este caso el nombre de archivo debe ser Prueba01.Ejecucion01.1x20.txt.

Ejecución de las Pruebas

3. En el mismo nodo presione el botón Configurar y seleccione el valor Guardar Nombre de Campo, también des-seleccione Guardar como XML. Presione el botón Hecho para finalizar.

Ejecución de las Pruebas

4. Guarde el script en Archivo —> Guardar.

5. Si no lo tiene abierto, abra JConsole y conéctelo a Tomcat para comenzar el monitoreo.

6. Cierre todos los programas que no necesite para la prueba.

7. Ejecute el script en Lanzar —> Arrancar y cuando finalice tome nota de los resultados. Para saber cuando acaba la ejecución puede ver las ventanas de logs y resultados o fíjese en el indicador de la parte superior derecha de JMeter que está en verde mientras se ejecuta el script.

Ejecución de las Pruebas

8. Probablemente nos pasó lo mismo en esta prueba. La peticiones 01, 02 y 03 fueron exitosas pero en todos los casos la 04 y 05 fallaron. Adjunto una imagen del reporte agregado de mi ejecución:

Ejecución de las Pruebas

En mi caso JConsole mostró un consumo de CPU del 50% durante la ejecución y consumo de memoria sostenido de unos 64 MB hasta que al parecer Tomcat dejó de responderle y se desconectó.

Ejecución de las Pruebas

El listener Ver Árbol de Resultados me muestra que el problema real ocurrió en la petición 4 y fue un OutOfMemoryError.

Ejecución de las Pruebas

Lo mismo me muestra el log de la consola de Tomcat.

Ejecución de las Pruebas

9. Conclusiones.

  • Esta primera prueba nos indica que hay serios problemas de memoria tanto de configuración como de consumo. El contenedor cayó con el primer usuario y su consumo de memoria no pasó de los 64 MB.
  • Esta primera caída es bloqueante y es necesario realizar ajustes antes de continuar con las pruebas.

Datos tomados para la prueba. Todos pueden salir del Informe Agregado:

Ejecución de las Pruebas

10. Guarde el log generado en esta prueba en una carpeta que indique la prueba y bórrelo de la carpeta de salida. Por ejemplo Intento01.Prueba01.Ejecución01.

11. En la sección de [optimizaciones de infraestructura] aplique la mejora del punto 3 donde se le asigna más memoria al contenedor.


Repetición Prueba 1 Ejecución 1.

Dado el fallo temprano del primer intento vamos a repetir esta prueba.

1. Reinicie Apache Tomcat.
2. Inicie JConsole y conéctelo al contenedor.
3. Asegúrese que borró el archivo de log anterior.
4. Limpie los datos de JMeter ejecutándolo o presionando CTRL+E. Asegúrese que los limpió.
5. Ejecute de nuevo el script y espere hasta que finalice.
6. Esta vez la ejecución fue exitosa. Aquí un resumen de gráficos y resultados registrados en la hoja de cálculo.

JConsole:

Ejecución de las Pruebas

Informe Agregado

Ejecución de las Pruebas

Datos registrados en la hoja de cálculo

Ejecución de las Pruebas

7. Conclusiones:

  • Esta vez la prueba fue exitosa y se establecieron tiempos de respuesta base.
  • El consumo de memoria para 20 ejecuciones del script fue de aproximadamente 220 MB. Con la memoria asignada podríamos esperar un máximo de 100 ejecuciones.
  • El tiempo promedio de respuesta fue de 123 milisegundos.

8. Si lo desea realice un gráfico comparativo entre estas dos primeras ejecuciones comparando el consumo de memoria y los tiempos de respuesta.


Prueba 1 Ejecución 2.

5 usuarios virtuales y un ciclo de 20 iteraciones.

1. Reinicie Apache Tomcat.
2. Inicie JConsole y conéctelo al contenedor.
3. Asegúrese que borró el archivo de log anterior.
4. Limpie los datos de JMeter ejecutándolo o presionando CTRL+E. Asegúrese que los limpió.
5. En el nodo Ver Resultados en Árbol cambie el archivo de log por Prueba01.Ejecucion02.5x20.txt.
6. Vaya al nodo Grupo de Hilos. En el campo Número de Hilos ingrese 5 y en Contador del bucle 20.

Ejecución de las Pruebas

7. Guarde el script.
8. Ejecute de nuevo el script y espere hasta que finalice.
9. Esta ejecución finalizó sin problemas. A continuación los datos más relevantes:

JConsole:

Ejecución de las Pruebas

Informe Agregado

Ejecución de las Pruebas

Datos registrados en la hoja de cálculo

Ejecución de las Pruebas

6. Conclusiones:

  • La prueba concluyó exitosamente.
  • El consumo de memoria subió hasta los 850 MB para las 100 ejecuciones del script (5 usuarios por 20 iteraciones).
  • El tiempo de respuesta promedio fue 129,2 milisegundos.

Prueba 1 Ejecución 3.

10 usuarios virtuales y un ciclo de 10 iteraciones.

1. Reinicie Apache Tomcat.
2. Inicie JConsole y conéctelo al contenedor.
3. Asegúrese que borró el archivo de log anterior.
4. Limpie los datos de JMeter ejecutándolo o presionando CTRL+E. Asegúrese que los limpió.
5. En el nodo Ver Resultados en Árbol cambie el archivo de log por Prueba01.Ejecucion03.10x10.txt
6. Vaya al nodo Grupo de Hilos. En el campo Número de Hilos ingrese 10 y en Contador del bucle 10.
7. Guarde el script.
8. Ejecute de nuevo el script y espere hasta que finalice.
9. La ejecución fue exitosa. A continuación los datos más relevantes:

JConsole:

Ejecución de las Pruebas

Informe Agregado

Ejecución de las Pruebas

Datos registrados en la hoja de cálculo

Ejecución de las Pruebas

6. Conclusiones:

  • La prueba concluyó con exitósamente.
  • El consumo de memoria subió hasta los 880 MB en las 100 ejecuciones del script.
  • El tiempo de respuesta promedio fue de 203 milisegundos.

Prueba 1 Ejecución 4.

20 usuarios virtuales y un ciclo de 5 iteraciones.

1. Reinicie Apache Tomcat.
2. Inicie JConsole y conéctelo al contenedor.
3. Asegúrese que borró el archivo de log anterior.
4. Limpie los datos de JMeter ejecutándolo o presionando CTRL+E. Asegúrese que los limpió.
5. En el nodo Ver Resultados en Árbol cambie el archivo de log por Prueba01.Ejecucion04.20x5.txt
6. Vaya al nodo Grupo de Hilos. En el campo Número de Hilos ingrese 20 y en Contador del bucle 5.
7. Guarde el script.
8. Ejecute de nuevo el script y espere hasta que finalice.
9. Esta ejecución fue exitosa. A continuación imágenes con el resumen.

JConsole:

Ejecución de las Pruebas

El consumo de memoria llegó hasta los 1024 MB y quedó bloqueado en ese punto.

Informe Agregado

Ejecución de las Pruebas

Datos registrados en la hoja de cálculo

Ejecución de las Pruebas

6. Conclusiones:

  • La prueba concluyó exitosamente
  • El consumo de memoria subió hasta los cerca de 900 MB en las 100 ejecuciones del script.
  • El tiempo de respuesta promedio fue 425,8 milisegundos.

Prueba 1 Ejecución 5.

25 usuarios virtuales y un ciclo de 4 iteraciones.

1. Reinicie Apache Tomcat.
2. Inicie JConsole y conéctelo al contenedor.
3. Asegúrese que borró el archivo de log anterior.
4. Limpie los datos de JMeter ejecutándolo o presionando CTRL+E. Asegúrese que los limpió.
5. En el nodo Ver Resultados en Árbol cambie el archivo de log por Prueba01.Ejecucion05.25x4.txt
6. Vaya al nodo Grupo de Hilos. En el campo Número de Hilos ingrese 25 y en Contador del bucle 4.
7. Guarde el script.
8. Ejecute de nuevo el script y espere hasta que finalice.
9. Esta ejecución fue exitosa. A continuación imágenes con el resumen.

JConsole:

Ejecución de las Pruebas

El consumo de memoria llegó hasta los 1024 MB y quedó bloqueado en ese punto.

Informe Agregado

Ejecución de las Pruebas

Datos registrados en la hoja de cálculo

Ejecución de las Pruebas

6. Conclusiones:

  • La prueba concluyó exitosamente
  • El consumo de memoria subió hasta los cerca de 900 MB en las 100 ejecuciones del script.
  • El tiempo de respuesta promedio fue 425,8 milisegundos.

Prueba 1 Ejecución 6.

50 usuarios virtuales y un ciclo de 2 iteraciones.

1. Reinicie Apache Tomcat.
2. Inicie JConsole y conéctelo al contenedor.
3. Asegúrese que borró el archivo de log anterior.
4. Limpie los datos de JMeter ejecutándolo o presionando CTRL+E. Asegúrese que los limpió.
5. En el nodo Ver Resultados en Árbol cambie el archivo de log por Prueba01.Ejecucion06.50x2.txt
6. Vaya al nodo Grupo de Hilos. En el campo Número de Hilos ingrese 50 y en Contador del bucle 2.
7. Guarde el script.
8. Ejecute de nuevo el script y espere hasta que finalice.
9. Esta ejecución fue exitosa. A continuación imágenes con el resumen.

JConsole:

Ejecución de las Pruebas

El consumo de memoria llegó hasta los 1024 MB y quedó bloqueado en ese punto.

Informe Agregado

Ejecución de las Pruebas

Datos registrados en la hoja de cálculo

Ejecución de las Pruebas

6. Conclusiones:

  • La prueba concluyó exitosamente
  • El consumo de memoria subió más de 900 MB en las 100 ejecuciones del script.
  • El tiempo de respuesta promedio fue 1284,4 milisegundos.

Finalización del Ejercicio

  1. Termine con la ejecución del libreto.
  2. Almacene logs, hoja de cálculo, imágenes y todos los datos que haya recogido durante la prueba.
  3. Seleccione las peticiones más representativas y genere un gráfico con los tiempos de respuesta de cada uno.
  4. Aplique las optimizaciones recomendadas de [infraestructura] y [aplicaciones]. Puede aplicar estas optimizaciones por partes y ejecutar el script para sacar conclusiones de acuerdo a cada mejora.
  5. Despliegue la aplicación y ejecute de nuevo todo el libreto de pruebas.
  6. Genere gráficos comparativos entre las peticiones hechas antes de las optimizaciones y las realizadas después.
  7. Cree un reporte con los hallazgos, las optimizaciones realizadas y cuantifique las mejoras obtenidas.

Puede descargar la versión optimizada de la aplicación desde aquí.

Si no se indica lo contrario, el contenido de esta página se ofrece bajo Creative Commons Attribution-ShareAlike 3.0 License