Ejecución de JMeter distribuido (red local)

title

Una de las funcionalidades más transacendentales en JMeter es la ejecución distribuida, es una modalidad que permite escalar de manera horizontal el número de generadores de carga. Si bien es una modalidad poco conocida, es súmamente útil o efectiva cuando necesitamos ejecutar poco miles de hilos o usuarios virtuales.

¿Porqué es poco conocida?

Realmente es poco conocida porque existen empresas especializadas en brindar esta automatización en la nube como Flood.io, Blazemeter, Octoperf, entre otros. Aunado a ello esta puede ser una tarea laboriosa que puede consumir mucho tiempo, habría que medir el costo beneficio de implementar este esquema para algún caso en particular.

¿Cuando sería prudente realizar el esfuerzo?

Si tienes la necesidad de realizar una prueba de carga o estrés de entre 2,000 a 8,000 hilos o usuarios virtuales, te aconsejo utilizar este esquema. Más allá no te lo recomendaría porque el tiempo que puede tomar el crear, clonar, configurar y monitorear los generadores de carga, sobre todo si es una sola persona la designada para todas esas tareas. Para ejecuciones superiores a 8K te recomendaria buscar un opción de Cloud SaaS Load Testing como lo mencionamos con anterioridad o también utilizar contenedores, que será parte de esta serie de publicaciones de JMeter distribuido.

¿Cómo funciona?

Funciona en la modalidad maestro - esclavo, esto significa que requerimos de un nodo o servidor para fungir como controlador u orquestador y los servidores restantes serían esclavos o injectores de carga (generadores de carga). Este esquema solo funciona en equipos conectados dentro de la misma red, esto significa que tendríamos que realizar subneteo para tener todos los equipos interconectados. Sin más preambulos veámos lo que necesitamos:

  • Maestro aka Controlador aka Orquestador (Windows) x 1

    • Firewall apagado
    • Java 1.8+
    • JMeter 5.2.1
  • Esclavo aka Generador de carga aka Injector de carga (Linux Ubuntu) x 4

    • Java 1.8+
    • JMeter 5.2.1

La versión de JMeter 5.2.1 deberá ser la misma en todos los equipos, la versión de Java es diferente en el maestro a los esclavos, pero lo recomendable es utilizar la misma version de Java en todos los equipos.

Receta de cocina

Paso #1

Debemos desactivar el firewall de Window para permitir la conexión bi-direccional entre el maestro y los esclavos. Elegí Windows Server 2019 para este ejemplo porque es más fácil mostrar la ejecución en el ambiente gráfico, aunque también pudieras utilizar Linux GUI. También es posible realizarlo desde el CLI, al final mostrare un ejemplo que sería de gran utilizad de no contar con ambiente gráfico o para los amantes del CLI.

firewall

Paso #2

Instalar Java 1.8+, para este ejemplo utilizé Java 1.8 JRE, puedes decargar la última versión de Java aquí.

java

Paso #3

Descargar e instalar JMeter 5.2.1 (última version conocida hasta esta publicación), si tienes duda puedes ver esta guía. En caso de necesitar Plugins o archivos de datos (CSV o imágenes), tendrás que instalarlos o copiarlos manualmente en cada denerador de carga, puesto que que estos archivos no se transmiten por RMI.

Paso #4

Editar el archivo jmeter.properties para anexar las direcciones IP de los remote hosts o esclavos (ver paso #6) y también para desactivar la seguridad del RMI. Es un proceso más largo habilitando la seguridad, pero vamos primero por el camino sencillo.

#remote_hosts=127.0.0.1  //original

 remote_hosts=10.223.2.71,10.223.2.78,10.223.2.63,10.223.2.58  //editada
#server.rmi.ssl.disable=false   //original

 server.rmi.ssl.disable=true     //editada

Paso #5

Instalar Java 1.8+ en cada uno de los esclavos, aúnque si estás utilizando servicios en la nube, te recomiendo realizar esta tarea una sola vez y crear una imagen para generar los demás servidores apartir de esa imágen. Aunque de todas formas deberás verificar los siguientes pasos para cada uno de los esclavos. Para este ejemplo utilizé Linux Ubuntu, aquí podrás ver una receta de instalación.

linux

Paso #6

Descargar e instalar JMeter 5.2.1 (última version conocida hasta esta publicación), si tienes duda puedes ver esta guía. Podemos utilizar un simple wget para descargar la version tar ball, para descomprimirla podemos utilizar el comando tar.

wget https://downloads.apache.org//jmeter/binaries/apache-jmeter-5.2.1.tgz

 tar -xvf apache-jmeter-5.2.1.tgz

Paso #7

Obtener la dirección IP de cada uno de los servidores esclavos para insertarla en el paso #4, podría parecer recursivo, pero es necesario este valor para el paso #4 y el paso #9. La manera más sencilla de obtener el valor es utilizando el comando ifconfig, con base en la siguiente imagen la dirección IP sería: 10.223.2.71

ifconfig

Paso #8

Editar el archivo jmeter.properies en los esclavos para desactivar la seguridad del RMI. Como ya lo había mencionado es un proceso un poco más largo habilitando la seguridad, pero dado que estamos en un red local no debería ser necesaria.

#server.rmi.ssl.disable=false   //original

 server.rmi.ssl.disable=true     //editada

Paso #9

Editar el archivo jmeter-server, este archivo contiene la configuración del servicio JMeter para el modo remote host o esclavo, en otras palabras debemos configurar la dirección IP de la red interna del esclavo para que esté pueda recibir las peticiones del maestro o controlador.

#RMI_HOST_DEF=-Djava.rmi.server.hostname=xxx.xxx.xxx.xxx   //original

 RMI_HOST_DEF=-Djava.rmi.server.hostname=10.223.2.71     //editada

Paso #10

Iniciar el servicio jmeter-server, este servicio necesita ser ejecutado para que el esclavo escuché los comandos del maestro. Te recomiendo utilizar nohup y atrapar la tarea en background con &, esto en caso de que pierdas la conexión SSH con el esclavo, pero el servicio siga funcionando. Sería algo así:

nohup ./jmeter-server &

 tail -f nohup.out

Al final te recomiendo dejar la sesión SSH monitoreando el archivo de salida nohup.out con el comando tail.

monitoring

Paso #11

Una vez que esten configurados y escuchando los esclavos, estos serán visibles para el maestro o controlador, para este ejemplo utilice un script con poca carga, solo 10 hilos. Cabe mencionar que son 10 hilos por cada generador, en total tendría 40 hilos ejecutandose concurrentemente.

nodes

start

Paso #12

Validar que los esclavos están reciviendo la comunicación del maestro y ejecutando el script.

jmeter-log

Espero hayan podido reproducir este escenario, si no lograron el cometido, chequen que TODOS los esclavos y maestro esten dentro de la misma red. En mi ejemplo estan en la red 10.223.2.0/24. Si están utilizando AWS o Azure, debemos asegurarnos que estén dentro de la misma subnet y vpc. Próximamente publicaré como podemos ver estos resultados en Grafana.

Para finalizar les dejo la ejecución desde línea de comando:

jmeter.bat -n -t script.jmx -R 10.223.2.71,10.223.2.78,10.223.2.63,10.223.2.58

cli

Conclusión

Este mecanismo bien sobre Azure y AWS que son de los más grandes proveedores de Cloud IaaS en la nube, no lo he probado en Google pero me imagino que también debe funcionar. Como podrán observar aquí seguimos haciendo tareas manuales que deben ser evaluadas en costo-beneficio, debido a que estas tareas podrian llevar algo de practica para obtener mayor habilidad y sobre todo fallar un poco para ver las posibles vertientes en las cuales pudieramos atorarnos. No duden en contactarme si necesitan ayuda.

Saludos.

-Antonio