En este momento estás viendo Planificación de Pruebas de Rendimiento en Sistemas Monolíticos con Apache JMeter

Planificación de Pruebas de Rendimiento en Sistemas Monolíticos con Apache JMeter

En este artículo te comparto un enfoque para aplicar una estrategia detallada y un conjunto de escenarios de prueba estructurados en formato Gherkin, diseñados específicamente para evaluar el rendimiento, estabilidad y límites de un sistema bajo una arquitectura monolítica tradicional de tres capas (Frontend, Backend y Base de Datos compartida en un único servidor).

Pruebas de rendimiento en sistemas monolíticos con JMeter

1. Fundamento arquitectónico y modos de fallo comunes

De acuerdo con las mejores prácticas, las características de un sistema monolítico tienen profundas implicaciones en cómo se planifican, ejecutan e interpretan las pruebas de rendimiento:

A. Implicaciones clave del sistema monolítico en performance testing

  1. Recursos de hardware compartidos (CPU, Memoria, E/S): Al residir toda la lógica en una única unidad ejecutable, las operaciones pesadas de un módulo secundario (ej. generación de PDF en «Reportes») consumen la CPU, RAM y E/S del servidor que atiende a módulos críticos (ej. «Autenticación» o «Procesamiento de Pagos»).
  2. Pool de conexiones de base de datos único: La base de datos es típicamente un único punto de contención. Una consulta mal optimizada en cualquier módulo puede agotar el pool de conexiones del backend, provocando una denegación de servicio interna en toda la aplicación.
  3. Escalabilidad vertical limitada: A diferencia de los microservicios que escalan horizontalmente de forma elástica por componente, el monolito requiere escalabilidad vertical (más hardware en la misma máquina). Esto introduce un punto de saturación física donde el costo de recursos crece de forma exponencial pero el rendimiento (Throughput) se estanca debido a la contención de hilos y bloqueos de sincronización.
  4. Punto único de fallo y degradación cascada: Un error de agotamiento de memoria (OutOfMemoryError en la JVM/CLR) en una funcionalidad menor provocará la caída total del proceso del monolito, interrumpiendo todas las transacciones activas de todos los usuarios.

2. Consideraciones de diseño, entorno y datos

Aquí debemos definir tres reglas inquebrantables de diseño:

  • Aislamiento del entorno: Las pruebas deben realizarse en un ambiente aislado que replique fielmente la infraestructura productiva (mismos núcleos de CPU, RAM, configuración del servidor web/aplicaciones y parámetros de la Base de Datos). Esto evita interferencias externas y garantiza la repetibilidad de los resultados.
  • Diversidad y realismo de datos: No se debe probar con un único ID de usuario. Si se consulta la base de datos repetidamente con los mismos parámetros, la base de datos resolverá las consultas en caché, ocultando problemas de índices o cuellos de botella reales en disco. Utilizaremos el componente CSV Data Set Config de JMeter para inyectar datos variados.
  • Correlación y parametrización (PtU JMeter): Es crítico manejar de forma dinámica los identificadores de sesión (IDs de sesión, tokens JWT, tokens anti-CSRF) mediante extractores de expresiones regulares (Regular Expression Extractor) o extractores JSON (JSON Extractor) para garantizar que el servidor procese cada petición como un usuario único y real.

3. Set de escenarios y casos de prueba (formato Gherkin)

A continuación, clasifico los escenarios según su prioridad de ejecución técnica para un sistema monolítico.

Prioridad 1: ALTA (Validación crítica de estabilidad y recursos compartidos)

Caso 1.1: Prueba de carga de la línea base (Load Testing) – concurrencia cruzada

  • Objetivo: Establecer el comportamiento del sistema bajo la carga esperada (pico operativo diario) y verificar que el pool de conexiones de la Base de Datos compartida y la CPU del servidor monolítico no se degraden al operar múltiples módulos en paralelo.
  • Entradas (Inputs) requeridas:
    • Configuración JMeter (Thread Group): * Cantidad de hilos (usuarios concurrentes): 200 usuarios activos simultáneos.
      • Tiempo de Ramp-up: 5 minutos (para simular un crecimiento de carga ordenado).
      • Duración de la prueba en estado estable: 1 hora.
      • Temporizador (Precise Throughput Timer o Constant Timer): Simular un tiempo de pensamiento («Think Time») de 3 a 5 segundos por usuario para emular comportamiento humano real.
    • Datos de entrada: Archivo CSV parametrizado con 1,000 credenciales de usuarios únicos y un set de datos de búsqueda aleatorios para evitar que el motor de Base de Datos use caché persistente.
    • Infraestructura: Servidor monolítico al 10% de carga inicial (línea base libre de procesos zombies).
  • Escenario Gherkin:
Característica: Evaluación de rendimiento y concurrencia bajo carga normal esperada

  Escenario: Prueba de carga concurrente cruzada en los módulos del sistema monolítico
    Dado que el entorno de pruebas de rendimiento está completamente aislado de interferencias externas
    Y que el servidor monolítico cuenta con sus recursos de hardware (CPU, RAM) en valores basales estables
    Y que se cuenta con un archivo CSV con 1000 usuarios parametrizados y dinámicos para evitar almacenamiento en caché
    Cuando se inicia la prueba de carga en JMeter configurando 200 hilos concurrentes con un ramp-up de 5 minutos
    Y los usuarios virtuales ejecutan flujos combinados de "Login", "Búsqueda de Catálogo" y "Checkout de Compra" durante 1 hora
    Y se utiliza un temporizador para simular un Think Time promedio de 4 segundos entre transacciones
    Entonces el tiempo de respuesta promedio (Average Response Time) de todas las transacciones debe ser inferior a 1500 ms
    Y el percentil 90 (p90) del tiempo de respuesta no debe exceder los 2500 ms
    Y el porcentaje de transacciones fallidas o con error HTTP (Error Rate) debe ser del 0%
    Y la utilización de CPU del servidor monolítico debe estabilizarse por debajo del 70% sin presentar estrangulamiento (throttling)
  • Salidas esperadas (Outputs):
    • Reporte de JMeter (Summary Report / Reporte HTML): Gráficos de Response Time Over Time estables. Rendimiento (Throughput) de transacciones constante.
    • Métricas de infraestructura: El pool de conexiones de la Base de Datos muestra conexiones activas estables (ej. 45/100 conexiones máximas) sin encolamiento de peticiones.

Caso 1.2: Prueba de resistencia (Endurance/Soak Testing) – Fuga de memoria sostenida

  • Objetivo: Validar la estabilidad del monolito durante períodos prolongados para detectar fugas de memoria, fragmentación de memoria Heap de la máquina virtual (JVM/.NET CLR) y degradación lenta de los tiempos de respuesta. En un monolito, una fuga de memoria en un servicio menor (como reportes pesados) consume recursos críticos de la memoria compartida global del proceso.
  • Entradas (Inputs) requeridas:
    • Configuración JMeter (Thread Group): * Cantidad de hilos (usuarios concurrentes): 50 usuarios concurrentes constantes.
      • Tiempo de Ramp-up: 2 minutos.
      • Duración de la prueba: 6 horas continuas.
    • Datos de entrada: Parámetros de consulta dinámicos y recurrentes provistos mediante un CSV Data Set Config.
    • Infraestructura: Monitorización activa de la memoria del proceso (ej. JVM Heap Allocation, uso de Garbage Collector).
  • Escenario Gherkin:
Característica: Evaluación de estabilidad a largo plazo para detección de fugas de memoria

  Escenario: Prueba de resistencia ejecutando tareas repetitivas y generación de reportes
    Dado que el entorno monolítico está aislado y libre de tareas administrativas programadas concurrentes
    Y que se habilita la monitorización en tiempo real de la memoria física y del Heap de la máquina virtual del sistema
    Cuando ejecuto una prueba de resistencia en JMeter con 50 usuarios virtuales concurrentes durante 6 horas continuas
    Y los usuarios realizan de forma repetida flujos de consulta de datos y generación de reportes pesados en formato PDF
    Entonces la tasa de errores (Error Rate) de transacciones debe mantenerse por debajo del 0.1% a lo largo de toda la ejecución
    Y el tiempo de respuesta promedio en la sexta hora no debe mostrar una degradación mayor al 15% respecto a la primera hora
    Y el tamaño del montón de memoria (JVM Heap Memory) debe retornar a su línea base tras las ejecuciones del Garbage Collector (patrón de diente de sierra regular)
    Y no se debe registrar ningún error de tipo OutOfMemory o caídas del proceso ejecutable al finalizar la prueba
  • Salidas esperadas (Outputs):
    • Reporte de JMeter: Tendencia plana en los tiempos de respuesta.
    • Métricas de infraestructura: Patrón de liberación de memoria de tipo «Diente de Sierra» saludable. No hay acumulación persistente de objetos no referenciados que la Garbage Collection no pueda liberar.

Prioridad 2: MEDIA (Determinación de límites y capacidad de absorción)

Caso 2.1: Prueba de Estrés (Stress Testing) – Punto de saturación y degradación en cascada

  • Objetivo: Empujar el sistema monolítico más allá de sus límites operativos normales para identificar la capacidad máxima (Throughput límite), encontrar el primer cuello de botella (CPU, Memoria o Conexiones DB) y observar cómo se degrada el monolito. En particular, verificar si al fallar un módulo (ej. colapso de consultas a BD), el sistema completo se cae o si el servidor web encola de forma ordenada los hilos de atención (Thread Starvation).
  • Entradas (Inputs) requeridas:
    • Configuración JMeter (Stepping Thread Group / Concurrency Thread Group):
      • Carga incremental por escalones: Comenzar con 100 usuarios e incrementar 50 usuarios cada 5 minutos hasta alcanzar los 800 usuarios concurrentes o hasta que la tasa de error comience a escalar.
      • Duración de cada escalón: 5 minutos.
    • Datos de entrada: CSV extenso con credenciales para garantizar el realismo de los perfiles de carga definidos en la fase de análisis (según ISTQB-PT).
    • Infraestructura: Registro de logs de error del servidor de aplicaciones y base de datos para capturar fallos bajo el punto de quiebre.
  • Escenario Gherkin:
Característica: Determinación del punto de quiebre y comportamiento de la degradación del sistema

  Escenario: Prueba de estrés incremental hasta la saturación del servidor monolítico único
    Dado que el sistema se encuentra operativo y los servicios de monitoreo de red y hardware están activos
    Cuando ejecuto una prueba en JMeter incrementando la carga por escalones de 50 usuarios cada 5 minutos, desde 100 hasta 800 hilos concurrentes
    Y se procesa un volumen sostenido de transacciones críticas en el único servidor disponible
    Entonces se debe identificar con precisión el punto de quiebre del sistema donde el Throughput (peticiones/segundo) se estanque o comience a descender
    Y la degradación del sistema debe presentarse de manera controlada (ej. incremento controlado de tiempos de respuesta sin caídas abruptas del servicio)
    Y el sistema debe recuperarse automáticamente y normalizar sus tiempos de respuesta una vez que la carga de usuarios concurrentes regrese a valores normales
    Y se deben registrar los cuellos de botella del monolito en los componentes compartidos (ej. agotamiento de hilos HTTP en Tomcat o bloqueos de tablas de Base de Datos)
  • Salidas esperadas (Outputs):
    • Reporte de JMeter (Response Times vs Active Threads): Identificación del «Knee Point» (punto donde la latencia aumenta exponencialmente y el rendimiento deja de escalar linealmente).
    • Métricas de Infraestructura: El servidor arroja códigos HTTP 503 (Servicio No Disponible) o de timeout de conexiones en lugar de caerse por completo, mostrando una degradación ordenada y protegiendo el almacenamiento de la base de datos de corrupciones.

Caso 2.2: Prueba de Picos (Spike Testing) – Contención del pool de hilos del servidor web

  • Objetivo: Simular un aumento súbito e inesperado de tráfico en el único punto de entrada de la aplicación monolítica (ej. campañas de marketing masivas). Esto evalúa la capacidad del pool de hilos del servidor web (como los hilos de Tomcat/IIS) para encolar o descartar peticiones de forma ágil sin quedarse sin recursos de sockets ni bloquear permanentemente al sistema.
  • Entradas (Inputs) Requeridas:
    • Configuración JMeter (Ultimate Thread Group):
      • Línea base: 20 usuarios activos durante 2 minutos.
      • Pico: Subida repentina a 400 usuarios concurrentes en un lapso de 10 segundos.
      • Sostenimiento del pico: 1 minuto.
      • Descenso: Retorno a 20 usuarios activos en 10 segundos.
    • Datos de entrada: Flujos transaccionales rápidos (ej. Login y Ver Estado de Pedido).
  • Escenario Gherkin:
Característica: Resiliencia ante ráfagas súbitas de tráfico masivo concurrente

  Escenario: Prueba de picos repentinos para evaluar la gestión del pool de hilos de entrada
    Dado que el servidor web de la aplicación monolítica tiene configurado su límite estándar de hilos de atención concurrentes
    Cuando ejecuto un perfil de carga en JMeter que incrementa abruptamente el volumen de usuarios de 20 a 400 en un intervalo de 10 segundos
    Y mantiene ese pico de tráfico intenso durante 1 minuto antes de descender nuevamente a 20 usuarios
    Entonces el pool de hilos del servidor debe procesar las peticiones encoladas sin generar denegaciones de conexión a nivel de socket (Connection Refused)
    Y el servidor monolítico no debe presentar bloqueos totales permanentes (Deadlocks) durante el pico de carga
    Y tras superar el pico de tráfico, los tiempos de respuesta de los usuarios que permanecen en el sistema deben volver a los valores de la línea base en menos de 120 segundos
  • Salidas esperadas (Outputs):
    • Reporte de JMeter: Curva de Throughput que sigue la silueta del pico de hilos de JMeter. Registros mínimos de errores (tolerancia de < 5% de errores transitorios durante la transición del pico).
    • Métricas de infraestructura: El pool de hilos del servidor web de aplicaciones llega a su uso máximo (100% de hilos ocupados) y los encola temporalmente (Thread Queue Length aumenta pero se vacía rápidamente después del pico).

Prioridad 3: BAJA (Análisis de capacidad de infraestructura a futuro)

Caso 3.1: Prueba de escalabilidad vertical – Verificación de rendimientos decrecientes

  • Objetivo: Analizar la relación coste/beneficio y escalabilidad del monolito. Consiste en ejecutar el mismo test de carga media-alta en dos configuraciones físicas distintas (ej. 4 vCPU / 8 GB RAM vs. 8 vCPU / 16 GB RAM) para verificar si el sistema monolítico es capaz de aprovechar el hardware adicional de manera eficiente, o si el rendimiento se ve limitado por cuellos de botella de software de un único proceso (ej. bloqueos de hilo internos del servidor de aplicaciones).
  • Entradas (Inputs) requeridas:
    • Configuración JMeter:
      • Perfil de carga fija y estable de alta demanda: 400 usuarios concurrentes fijos por 30 minutos.
    • Variables del entorno:
      • Ejecución 1: En entorno con configuración basal de hardware de servidor.
      • Ejecución 2: En el mismo entorno duplicando sus recursos de CPU/RAM (Escalado Vertical).
    • Datos de entrada: Conjunto masivo de datos transaccionales idénticos en ambas corridas para asegurar la consistencia.
  • Escenario Gherkin:
Característica: Validación de la eficiencia del escalado vertical en entornos monolíticos

  Escenario: Prueba de escalabilidad comparativa bajo incremento de capacidad de hardware
    Dado que se han configurado dos instancias de pruebas aisladas con diferencias proporcionales en capacidad de hardware (CPU/RAM)
    Y que se cuenta con la base de datos poblada de forma idéntica en ambas configuraciones
    Cuando ejecuto la misma prueba de carga de 400 usuarios concurrentes en JMeter sobre el servidor monolítico original
    Y posteriormente ejecuto la misma prueba sobre el servidor monolítico escalado verticalmente (con el doble de recursos de hardware)
    Entonces el Throughput (peticiones procesadas por segundo) en el servidor escalado debe mostrar una mejora proporcional de rendimiento de al menos un 40% respecto al original
    Y los tiempos de respuesta promedio en la máquina de mayores especificaciones deben disminuir correlativamente
    Y no se deben registrar cuellos de botella internos relacionados a contención de hilos de software que anulen las mejoras del hardware adicional
  • Salidas esperadas (Outputs):
    • Reporte de JMeter (Comparativo): Comparación directa del Throughput promedio y percentiles 95 de tiempos de respuesta de ambas ejecuciones.
    • Métricas de infraestructura: El uso de CPU en la máquina más grande debe distribuirse uniformemente entre los núcleos habilitados, asegurando que la aplicación monolítica aprovecha el paralelismo del procesador multipoceso y no posee procesos bloqueantes mono-hilo.

4. Resumen de entradas y salidas técnicas para JMeter

Para estructurar la ejecución y automatización dentro de Apache JMeter, se recopila la matriz de entradas y salidas técnicas clave aplicables a estos escenarios:

ID CasoTipo de PruebaConfiguración JMeter (Inputs)Datos Clave Necesarios (Inputs)KPIs del SLA Esperados (Outputs)Métricas de Sistema Esperadas (Outputs)
1.1Carga200 hilos, Ramp-up 5 min, Duración 1 hora. Think Time 4s.CSV con 1000 usuarios + parámetros de búsqueda variados.Tiempo respuesta medio < 1500 ms, p90 < 2500 ms, error = 0%.CPU < 70%, Pool de conexiones DB estable (< 50% de saturación).
1.2Resistencia50 hilos constantes, Duración 6 horas continuas.CSV con datos dinámicos transaccionales, Token correlacionado.Tiempos de respuesta estables (desviación < 15%), error < 0.1%.Memoria Heap de JVM estable, comportamiento diente de sierra normal. No OOM.
2.1EstrésEscalones de 50 hilos c/5 min, de 100 a 800 hilos totales.CSV masivo de usuarios para evitar duplicados en la base de datos.Identificación del punto de saturación y degradación controlada.Alertas por exceso de encolamiento de hilos o bloqueos de DB (Ej. Locks).
2.2PicosSalto de 20 a 400 hilos en 10 seg. Sostener 1 min.Flujos rápidos transaccionales parametrizados (Login).Recuperación automática del sistema tras pico. Error temporal < 5%.Pool de hilos de Tomcat/IIS máximo, pero sin caídas físicas de sockets.
3.1Escalabilidad400 hilos constantes por 30 minutos (Ejecutado en Hardware A vs B).Mismo conjunto masivo de datos de entrada estructurado.Mejora de rendimiento (Throughput) de al menos un 40% en Hardware B.Distribución homogénea de hilos entre los cores de CPU adicionales.

5. Recomendaciones de Implementación y Monitoreo en JMeter

  • Uso del modo No-GUI: Todas las pruebas de carga, resistencia, estrés y picos deben ejecutarse desde la terminal (CLI) usando la sintaxis:jmeter -n -t plan_de_pruebas.jmx -l resultados.jtl -e -o ./reporte-html Esto evita que la interfaz gráfica de JMeter consuma memoria RAM y CPU del generador de carga, garantizando resultados precisos y confiables (Mejor práctica recomendada en el material de estudios de JMeter).
  • Asignación de Memoria Heap del Generador: Ajustar la variable JVM_ARGS="-Xms1g -Xmx1g" en el script de arranque de JMeter antes de ejecutar pruebas pesadas para que el inyector de carga no sea el cuello de botella.
  • Monitoreo Externo Completo: La monitorización del monolito debe incluir simultáneamente el sistema operativo (CPU, E/S de disco, uso de swap), el motor de ejecución web (hilos asignados/libres, recolección de basura) y el motor de base de datos (conexiones simultáneas activas, transacciones confirmadas por segundo y consultas lentas / slow queries).

Puedes seguir mis publicaciones y contactarme por DM desde LinkedIn.

Muchas gracias.

Gus Terrera

Apasionado por el agile testing y la ia.