Pruebas de rendimiento con Jmeter en CloudHub 1.0

Introducción

En este manual vamos a explicar las mejores practicas para poder hacer pruebas de rendimiento sobre las muleApps deplegadas en CloudHub 1.0

Infraestructura

Antes de nada es necesario explicar un poco la infraestructura de CloudHub 1.0 en el siguiente diagrama:

En el diagrama podemos observar las características que tiene la infraestructura de CloudHub 1.0 y también sus limitaciones de dimensionamiento

Cada MuleApp se aloja en una máquina EC2 de AWS, que según los vCores que le asignemos, la máquina tendrá más o menos potencia.

  • Nube propia de MuleSoft basada en AWS.
  • Integración nativa con Anypoint Platform (Api Manager, Monitoring, …).
  • Infraestructura incluida en el precio de licenciamiento.
  • Comunicaciones con infraestructura cliente:
  • VPC: Virtual Private Cloud
  • VPN: Virtual Private Network
  • Transist Gateway: Producto de AWS que facilita la configuración de las comunicaciones.
  • Capacitación de API: los recursos que se le pueden asignar a cada API son los siguientes (0.1 , 0.2, 1, 2, …)

Diseño de apis y el problema del dimensionamiento de CloudHub

Para diseñar las API en Mule es necesario tener en cuenta el tipo de infraestructura sobre la que vamos a desplegarlas.

El dimensionamiento de CloudHub es:

  • 0.1 vCore (500 MB de memoria)
  • 0.2 vCore (1 GB de memoria)
  • 1 vCore (2 GB de memoria)
  • 2 vCore (4 GB de memoria)
  • 4 vCore (8 GB de memoria)
  • 8 vCore (16 GB de memoria)
  • 16 vCore (32 GB de memoria)

El coste de 1 vCore todos sabemos lo que vale, por lo que es muy importante aprovechar al máximo los recursos y diseñar correctamente las MuleApp para que se puedan dimensionar de forma correcta.

Por este motivo es muy importante que nuestras MuleApp puedan funcionar como mucho con 0.2 vCore, y que si necesitamos más potencia, lo hagamos con un escalado horizontal (aumentar las réplicas/workers)

Buenas prácticas de diseño de APIs con MuleSoft

Si hacemos un mal diseño de las API´s nos quedará una cosa así, y no estaremos aprovechando los recursos de CloudHub

si hacemos un buen diseño de las APIs quedará una cosa así

por este motivo es necesario seguir estas sencillas reglas

1.- Máximo de operaciones por MuleApps: se recomienda entre 20–25 operaciones por MuleApps

2- Estudio de volumetrías de las operaciones:

Aquellas operaciones que tengan mucha volumetría, deberían de estar separadas en MuleApps independientes, por si es necesario crear más réplicas, que sea solo de las operaciones que más lo demandan.

No es lo mismo (0.1 vcore x 0.1 vcore x 0.1 vcore = 0.3 vcore), que (1 vcore x 1 vcore x 1 vcore = 3 vcores) Si no se hace bien se pueden crear aplicaciones que tengan operaciones con mucha volumetría y con otras operaciones que no tengan apenas.

3.- Estudio del tamaño de los mensajes: Cada petición que llega a un API de MuleSoft es un hijo de Java y un trozo de memoria. Es muy importante saber el tamaño del mensaje porque eso repercute directamente en el performance del API. Se recomienda que aquellas operaciones que manipulen peticiones de gran tamaño se separen en MuleApps independientes, para que no afecten al resto de operaciones con menos tamaño y quizás más volumetría de mensajes.

Pruebas de rendimiento con JMeter

Cómo organizar las pruebas

Lo primero es explicar cómo tenemos que organizar las pruebas, dentro de JMeter y para ello tenemos que crear dentro del proyecto los elementos Thread Group y dentro

Dentro de cada Thread group es necesario que pongamos los siguientes elementos

  • HTTP Header Manager: Para configurar los parámetros de cabecera de la petición
  • HTTP Request: Este es el elemento principal donde se configura todos los parámetros de la petición:

Parámetros

Body

protocolo

host

  • View Result Tree y Table: estos componentes sirven para ver los resultados y en formato árbol y tabla

Combinación de pruebas en JMeter para CloudHub 1.0

En este apartado os voy a explicar como realizar las combinaciones de parámetros para poder realizar unas pruebas que pongan en apuros a la infraestructura de nuestras API´s :)

Vamos a jugar con los siguientes parámetros:

JMeter:

Thread Group:

  • Number of Threads (users): Número de peticiones o usuarios concurrentes
  • Ramp-up period (second): Rango de tiempo (de 0 al valor indicado) en el que se lanzan todo el número de Threads
  • Loop Count: número de iteraciones

Anypoint Platform

  • Worker size: Establece la potencia de cpu y memoria (0.1, 0.2, 1, 2, 4,…)
  • Replicas / Workers: Número de replicar concurrentes

Caso 1

JMeter

  • Number of Threads (users): 10
  • Ramp-up period (second): 1
  • Loop Count: 1

Anypoint Platform

  • Workers size: 0.1
  • Replicas / Workers: 1

JMeter

  • Number of Threads (users): 50
  • Ramp-up period (second): 5
  • Loop Count: 1

Anypoint Platform

  • Workers size: 0.1
  • Replicas / Workers: 1

JMeter

  • Number of Threads (users): 100
  • Ramp-up period (second): 5
  • Loop Count: 1

Anypoint Platform

  • Workers size: 0.1
  • Replicas / Workers: 1

JMeter

  • Number of Threads (users): 200
  • Ramp-up period (second): 10
  • Loop Count: 1

Anypoint Platform

  • Workers size: 0.1
  • Replicas / Workers: 1

JMeter

  • Number of Threads (users): 500
  • Ramp-up period (second): 15
  • Loop Count: 1

Anypoint Platform

  • Workers size: 0.1
  • Replicas / Workers: 1

JMeter

  • Number of Threads (users): 1000
  • Ramp-up period (second): 20
  • Loop Count: 1

Anypoint Platform

  • Workers size: 0.1
  • Replicas / Workers: 1

Si la MuleApps está bien construida no debería de dar problemas con estos parámetros, pero si queremos poner al límite y empezar a ver fallos en las peticiones tendremos que jugar un poco con los parámetros

JMeter

  • Number of Threads (users): 500
  • Ramp-up period (second): 5
  • Loop Count: 2

Anypoint Platform

  • Workers size: 0.1
  • Replicas / Workers: 1

JMeter

  • Number of Threads (users): 1000
  • Ramp-up period (second): 10
  • Loop Count: 2

Anypoint Platform

  • Workers size: 0.1
  • Replicas / Workers: 1

Con estos parámetros ya empezaremos a ver ciertos fallos:

  • 504 Timeout
  • 503 Service unavailable

una vez que empezamos a encontrar fallos, tenemos que utilizar los mismos parámetros de Jmeter pero aumentando los Workers size y las réplicas de forma que empecemos a ver menos fallos en los resultados, por ejemplo con las siguientes combinaciones

Anypoint Platform

  • Workers size: 0.2
  • Replicas / Workers: 1
  • Workers size: 0.2
  • Replicas / Workers: 2

Identificar y optimizar los puntos de fallos

Cuando aparecen los fallos en las pruebas es lógico pensar que estos fallos pueden venir porque la infraestructura del API no puede soportar la carga de peticiones que se le está pasando, pero muchas veces son otros los motivos que hacen que un api no funcione de la forma más óptima posible.

  1. Revisión de los tiempos de respuesta de los elementos que salen de la MuleApp: Es necesario que todos los componente de un flujo de Mule tengan el timeout configurado para que no se quede el hilo de Java eternamente abierto.
  2. Configuración del pool de conexiones a las Bases de Datos: Si no se configura el pool de conexiones a las BD relacionales de nuestros flujos MuleSoft, y por defecto Java, establece conexiones cada vez que llegue una petición. Si configuramos el pool de conexiones y dejamos como mínimo una conexión abierta esta se mantiene y no se establece por cada peticion ganando mucho tiempo en cada petición.
  3. Uso inútil de For Each: Muchas veces por falta de conocimiento en programación se crean flujos for Each como resultado de una primera búsqueda de identificadores y un for each para poder obtener el detalle de cada uno de esos identificadores. Si se sabe hacer bien las consultas a BD se puede obtener en una sola consulta todo lo necesario para no tener que utilizar estructura de repetición innecesariamente

Conclusiones

Es importante que las MuleApps no necesiten 1 vcore para poder funcionar, porque eso quiere decir que no hemos diseñado correctamente la agrupación de operaciones dentro de nuestras APIs, por ello como mucho una MuleApp debería de funcionar con 0.2 vCores correctamente con las exigencias de volumetrías y tamaño de mensajes correctos, y si queremos darle mas potencia a nuestras API´s que sea de forma horizontal añadiendo mas replicas.

--

--