Para hacer pruebas de performance es fundamental entender cómo funciona una herramienta de simulación de carga. Las pruebas de rendimiento consisten en simular carga en el sistema bajo pruebas para analizar su desempeño durante la ejecución de la prueba, pudiendo encontrar cuellos de botella y oportunidades de mejora.
Para la simulación se utilizan herramientas específicas, en las que se debe automatizar las acciones que generarán esa carga, esto es: las interacciones entre el cliente y el servidor (digo cliente para no restringir a un usuario, ya que puede ser el tráfico desde un navegador, una app nativa, otra aplicación, etc.). Para poder simular muchos usuarios con poca infraestructura de pruebas, se automatizan las interacciones a nivel de protocolo, lo cual hace que la automatización sea más compleja (en cuanto al trabajo necesario para su preparación) que la automatización de pruebas funcionales, que se realiza a nivel de interfaz gráfica.
En este post quiero darte un panorama general de cómo funcionan estas herramientas a nivel conceptual, para que luego puedas concentrarte en estudiar cómo funciona alguna en particular.
¿Para qué hacer una prueba de performance?
Las pruebas de rendimiento son sumamente necesarias para reducir riesgos en la puesta en producción, logrando así analizar y mejorar el rendimiento de la aplicación y los servidores, al estar expuestos a usuarios concurrentes. Para ello se utilizan herramientas específicas (llamadas generadoras de carga) para simular la acción de múltiples usuarios concurrentes.
Realizando simulaciones de usuarios accediendo simulatáneamente al sistema, podremos responder a preguntas como:
- ¿La aplicación podrá responder adecuadamente a la carga esperada?
- ¿Cuántos usuarios podrá soportar el sistema antes de dejar de responder con tiempos de respuesta aceptables?
- ¿Qué tan rápido se recupera la aplicación luego de un pico de carga?
- ¿Cómo afecta a los usuarios la ejecución de determinado proceso?
- ¿Cuáles son los cuellos de botella del sistema?
- ¿Cómo cambia la performance del sistema al tener un gran volumen de datos?
- ¿Qué configuración es óptima para la operativa diaria?
- ¿Será la aplicación capaz de responder adecuadamente ese día en que tendrá mucha mayor carga que lo habitual?
¿Cómo se realiza una simulación de carga?
Las herramientas especializadas en realizar este tipo de simulaciones ejecutan cientos de threads (hilos, que podríamos pensarlo como pequeñas partes de un programa que ejecutan de manera concurrente). Estos hilos simulan las acciones que ejecutarían los usuarios reales, y por eso se los llama “usuarios virtuales“, y lo podríamos pensar como un robot que ejecuta un caso de prueba.
Estas herramientas que realizan la simulación se ejecutan desde máquinas dedicadas a la prueba. Las herramientas permiten generalmente utilizar varias máquinas en un esquema master-slave para distribuir la carga, ejecutando por ejemplo 500 usuarios desde cada máquina. El principal objetivo de este sistema de distribución de carga es que no podemos dejar que estas máquinas se sobrecarguen, porque de esa forma podrían invalidar la prueba, ya que se generarían problemas para simular la carga o para recolectar los datos de tiempos de respuesta, por ejemplo.
En la imagen queda representado cómo desde unas pocas máquinas se puede ejecutar gran cantidad de carga (usuarios virtuales) sobre nuestro sistema. Para el análisis de performance se necesitan expertos de distintas partes de la infraestructura (red, application servers, bases de datos, etc.) utilizando distintas herramientas de monitorización.
¿Cómo preparar los scripts para la simulación?
A diferencia de los scripts de pruebas funcionales, en estos scripts si bien se utiliza el enfoque de record and playback, no se graba a nivel de interfaz gráfica, sino que a nivel de protocolo de comunicación. Esto es porque en una prueba funcional al reproducir se ejecuta el navegador y se simulan las acciones del usuario sobre el mismo. En una prueba de rendimiento se van a simular múltiples usuarios desde una misma máquina, por lo que no es factible abrir gran cantidad de navegadores y simular las acciones sobre ellos, ya que la máquina utilizada para generar la carga tendría problemas de rendimiento, obteniendo así una prueba inválida. Al hacerlo a nivel de protocolo se puede decir que se “ahorran recursos”, ya que en el caso del protocolo HTTP lo que tendremos serán múltiples hilos que enviarán y recibirán texto por una conexión de red, y no tendrán que desplegar elementos gráficos ni ninguna otra cosa que exija mayor procesamiento.
Para preparar un script se procede en forma similar que para los scripts de pruebas funcionales, pero esta vez la herramienta en lugar de capturar las interacciones entre el usuario y el navegador, se captura los flujos de tráfico HTTP entre el cliente y el servidor (HTTP o el protocolo que se vaya a simular, y de nuevo, cliente puede ser el browser, una app nativa o lo que se quiera simular). Entonces, para la automatización se necesitan conocimientos sobre herramientas de automatización y protocolos de comunicación (HTTP, SIP, SOAP, ISO8583, etc.).
En la imagen queda representado que con herramientas como JMeter lo que sucede es cómo se “graba” la prueba, donde básicamente se abre un proxy que capturará el tráfico entre el cliente y el servidor. El script resultante será una secuencia de comandos en un lenguaje proporcionado por la herramienta utilizada, en el cual se manejen los requests y responses de acuerdo al protocolo de comunicación.
Una vez que se graba el script, es necesario luego realizar una serie de ajustes sobre estos elementos para que quede reproducible. Estos scripts serán ejecutados por usuarios concurrentes, y, por ejemplo, no tiene sentido que todos los usuarios utilicen el mismo nombre de usuario y clave para conectarse, o que todos los usuarios hagan la misma búsqueda (ya que en ese caso la aplicación funcionaría mejor que de usar diferentes valores, dado que influirían los cachés, tanto a nivel de base de datos como a nivel de servidor de aplicaciones Web).
El costo de este tipo de ajustes dependerá de la herramienta utilizada y de la aplicación bajo pruebas. En ocasiones es necesario ajustar cookies o variables, pues las obtenidas al grabar dejan de ser válidas, debiendo ser únicas por usuario. Se deberán ajustar parámetros, tanto del encabezado como del cuerpo del mensaje, etc.
Como comentario final, me gustaría destacar que hay una diferencia muy grande de esfuerzo entre preparar un script para un flujo de un usuario en un browser a que si quisiéramos preparar una prueba puntual para un endpoint específico de una API Rest.
Gracias por compartir información tan importante para el día a día de un Performance. Entender cómo trabaja una herramienta de performance es necesario para resolver todo tipo de problemas que se puedan presnetar. Inclusive desde el mismo diseño de los scripts.
Excelente explicación, gracias!
Me parece excelente el tema ya que aclara y explica la importancia de las pruebas de performance, considero que es una de las mas importantes ya que nos permite reducir el riesgo en la puesta en producción, logrando que la aplicación tenga el mejor rendimiento en la ejecución de sus procesos al estar expuesto a una cantidad elevada de usuarios recurrentes.