Cambios de comportamiento entre JMeter 4 y 5

Experimentando recientemente con JMeter 4 y 5 (las últimas versiones a la fecha) encontramos una diferencia muy importante en la forma en la que se comportan, para lo cual es necesario comprender muy bien la diferencia para poder realizar la simulación que deseamos. Básicamente las conexiones en JMeter 4 se mantienen abiertas entre iteraciones y en JMeter 5 se restablecen por completo, lo cual tiene dos implicancias que cambian drásticamente los resultados de la prueba: 

  • por un lado JMeter requiere más recursos para poder ejecutar, 
  • y por otro lado el tiempo de respuesta registrado será mayor que cuando se reutiliza la conexión. 

Ambas consecuencias son dadas por lo mismo: abrir una nueva conexión requiere más recursos y lleva más tiempo que utilizar una ya abierta.

En este post, preparado por Pablo Richieri de Abstracta, con colaboración de todo el equipo que trabaja en pruebas de performance y de Roger Abelenda (nuestro CTO) te contaremos cómo llegamos a esta conclusión y discutiremos las implicaciones que tiene como para poder tomar una decisión de cómo modelar tu prueba para simular a tus usuarios de la mejor manera. 

Experimentando con JMeter 5

Al ejecutar tests con la última versión disponible de JMeter (5.1) nos encontramos que con unos 30 usuarios virtuales el uso del CPU de la generadora de carga ya se saturaba llegando a un 100% durante casi la totalidad de la ejecución de la prueba. También pudimos ver que los tiempos de respuesta fueron elevados y en consecuencia la cantidad de pedidos por segundo fue baja.

Para entender por qué estaba sucediendo esto, luego de analizar distintas cosas, quisimos probar con una versión previa para verificar si esto también sucedía. Al ejecutar el mismo test con la versión 4.0 encontramos que teníamos considerablemente menos tiempo de respuesta, más pedidos por segundo y también menos uso de CPU que con la versión 5.1. Después de un poco de investigación encontramos que la principal diferencia en este comportamiento se manifestaba en el tiempo de conexión, y al revisar la documentación de cambios de JMeter nos encontramos con esto:

“Since JMeter 5.0, when using default HC4 Implementation, JMeter will reset HTTP state (SSL State + Connections) on each thread group iteration. If you don’t want this behaviour, set httpclient.reset_state_on_thread_group_iteration=false”

(Fuente: https://jmeter.apache.org/changes_history.html)

En definitiva: la conexión en JMeter 4 se mantiene abierta entre iteraciones y a partir de la versión 5 no. Esto genera que la misma prueba en JMeter 5 tenga mayores tiempos de respuesta, menores TPS y necesite más recursos para ejecutar. 

Evidencia 

A continuación podemos ver una tabla comparativa de los resultados obtenidos al ejecutar los test con diferentes versiones tanto de JMeter como de Java.

El script que se utilizó para esta prueba (origDemoblaze.jmx) fue creado con la versión 5.1 de JMeter y consiste simplemente en un solo pedido GET a la dirección http://dev.demoblaze.com seguido por un timer de 300 milisegundos para generar una mínima pausa entre pedido y pedido.

Les dejamos a continuación el codigo YAML del script Taurus a partir del cual se genera cada script de JMeter por si también querés experimentar con él.

 ---
 execution:
 - concurrency: 100
   hold-for: 10m
   ramp-up: 2m
   scenario: Thread Group
 scenarios:
   Thread Group:
     properties:
       httpclient.reset_state_on_thread_group_iteration: false
     requests:
     - follow-redirects: true
       label: HTTP Request
       method: GET
       think-time: 300ms
       url: https://dev.demoblaze.com:443/
     store-cache: false
     store-cookie: false
     use-dns-cache-mgr: false

En la tabla se puede ver fácilmente que los resultados obtenidos al usar la versión 4 de JMeter consumieron considerablemente menos recursos a las generadoras de carga y también lograron obtener más hits por segundo y un menor tiempo de respuesta.

Para esta segunda tabla comparativa retiramos el timer de 300 milisegundos y observamos los siguientes comportamientos.

A pesar de no ver más la significativa mejoría en el consumo de recursos de la generadora de carga en esta oportunidad, observamos que con el uso de la versión 4 de JMeter la cantidad de hits por segundo es notablemente superior y los tiempos de respuesta se ven reducidos en comparación a los obtenidos con la versión 5.

Simulando el comportamiento deseado

Pero esta gran diferencia ¿es algo positivo? El comportamiento por defecto de JMeter 5 ¿es el correcto? 

Todo depende de lo que estemos intentando simular en cada caso. Principalmente tenemos que pensar en que es lo que simula cada hilo que ejecutamos con JMeter. Un hilo ejecutará un script muchas veces hasta completar la prueba. Hay dos opciones, que un hilo simule a un usuario realizando muchas veces el mismo flujo de acciones (las automatizadas en el script) o que simule a diferentes usuarios, que acceden uno tras otro a realizar el mismo flujo. 

Hay que tener en cuenta que todo browser reutiliza conexiones. Si los usuarios que van a acceder al sistema van a realizar la misma tarea muchas veces, en realidad queremos que se reutilicen las conexiones (como lo hace JMeter 4). Si en cambio lo que vamos a simular son muchos usuarios uno tras otro, lo mejor es no reutilizar las conexiones (como lo hace JMeter 5). 

La idea que se tiene con este cambio es que cada iteración es como comenzar desde cero, como si fuera otro usuario, por lo que 1 usuario = 1 iteración de un hilo. De esta forma los hilos son simplemente un control de cuántos usuarios concurrentes podemos tener activos.

De todas formas con JMeter 5 podemos tener el mismo comportamiento que teníamos en la versión 4 usando un loop controller dentro de nuestro script. A continuación también les dejamos un nuevo script con un loop controller agregado para que puedan experimentar con el.

 ---
 execution:
 - concurrency: 100
   hold-for: 10m
   iterations: 1
   ramp-up: 2m
   scenario: Thread Group
 scenarios:
   Thread Group:
     requests:
     - do: []
       loop: 1
     - follow-redirects: true
       label: HTTP Request
       method: GET
       think-time: 300ms
       url: https://dev.demoblaze.com:443/
     store-cache: false
     store-cookie: false
     use-dns-cache-mgr: false 

La contrapartida de este nuevo funcionamiento de resetear todos los estados de conexión por cada hilo, limita la cantidad de usuarios virtuales que se pueden ejecutar por una misma generadora de carga ya que consume más recursos de las mismas. Esto supone tener que utilizar más generadoras de carga en algunos casos, aumentando los costos de la ejecución.

Cerrando

En conclusión, a la hora de utilizar JMeter debemos tener claro cómo es la situación que queremos simular, y las diferencias de comportamiento entre una versión y otra para así poder tomar la mejor decisión. Esta elección hará que nuestros resultados sean más cercanos a la realidad y así poder analizar mejor los riesgos de performance a los que nos enfrentamos. 

Leave a Reply

Your email address will not be published. Required fields are marked *