Por fin hemos pasado a producción, la aplicación ha terminado de ser desplegada en la plataforma accesible a los usuarios y podemos dar por terminada la iteración actual llena de crisis, nervios y sobreesfuerzos; que han culminado en un fin de semana de trabajo continuado.
Disfrutamos de un breve y merecido descanso antes de volver temprano a la oficina para arrancar la siguiente iteración, planificando las tareas a realizar y coordinando los equipos de desarrollo, UX y calidad.
Pero, la primera llamada a media mañana, ha despertado la pesadilla que se ha ido gestando según el número de accesos ascendía siguiendo al sol.
Y ahora – cuando los problemas se están escalando hacia Dirección como la espuma de un mal cava – un sistema sobrecargado ha terminado por presentar un rendimiento inutilizablemente lento.
Las pruebas como garantes del rendimiento
Cuando estoy describiendo el concepto de Ingeniería del rendimiento, una vez más, no estoy hablando de conceptos nuevos o recientes. Ya en 2004 Microsoft, el equipo de Patterns & Practices, publicó un detallado documento sobre este tipo de Ingeniería, que sería actualizado en el 2012 con una versión Agile.
Básicamente lo que se documenta es la necesidad de realizar una programación orientada al rendimiento, en donde se integre este tipo de pruebas en el ciclo de vida de las aplicaciones, asegurando que - en cada una de las etapas - el sistema funcione dentro del rango de prestaciones esperadas para que su funcionamiento sea el correcto.
Siendo el objetivo final de estos patrones y prácticas (procesos) la transformación desde una aproximación reactiva a otra proactiva, en relación al rendimiento de la plataforma de hardware y software sobre la que funcionan las aplicaciones.
Aproximación | Características |
---|---|
Reactivo |
|
Proactivo |
|
Los test unitarios, de integración, de sistemas o, incluso, los funcionales del Interfaz gráfico, están orientados a asegurar el funcionamiento correcto del código y de la aplicación con respecto a los requisitos funcionales.
Sin embargo, la Ingeniería del rendimiento se refiere a la necesidad de tener planes de prueba, lo más automatizados posibles, centrados en los requisitos no funcionales de la plataforma en donde se despliega y funciona el software.
Eso significa que estas pruebas están orientadas y dirigidas por el área de negocio. Quien realiza las priorizaciones de acuerdo a valores críticos del “business” como es el valor de los beneficios, la optimización de los costes o el impacto de los fallos del servicio.
Incluso puedo dar la vuelta a la tortilla, y utilizar los resultados de las baterías de pruebas como marco e indicador de la infraestructura necesaria para conseguir cumplir las expectativas. Definiendo el rendimiento de la aplicación primero y, luego, desarrollar el software orientado a cumplir el Plan de pruebas, para obtener unas prestaciones de ejecución determinadas.
Los cuatro test contra el apocalipsis
Como obliga cualquier proceso de construcción de software, lo primero que se necesita para definir el Plan de pruebas de rendimiento son: unos buenos requisitos. Con Criterios de Aceptación claros y bien detallados, que no dependan de interpretación y que – idealmente – puedan ser descritos de forma algorítmica con valores numéricos.
Por ejemplo: “Siendo un tipo de usuario determinado, el sistema debe devolver la respuesta de una búsqueda de clientes en menos de 5 segundos cuando están realizando búsquedas 250 usuarios de forma concurrente (no simultanea) en menos de 1 minuto. No superando los 10 segundos de respuesta cuando haya cargas puntuales de hasta 500 usuarios concurrentes.”
A estos requisitos, habría que añadirle aquellos que sean más técnicos, dependientes del hardware o de otras plataformas que deban ser integradas, y que se irán descubriendo durante todo el ciclo de vida de la aplicación.
En definitiva, deberé de construir una Pila de pruebas orientada a los cuatro tipos de test – y sus variantes – que se utilizaran para asegurar las prestaciones.
Test de carga
Los Test de Carga se llevan a cabo para asegurar que la aplicación cumple los objetivos de rendimiento esperados.
Con esta prueba se obtienen métricas sobre los tiempos de respuesta, las tasas de rendimiento y el consumo de recursos. Pudiendo señalar los puntos en donde empieza a fallar la aplicación, si aún no se ha llegado a los límites de sobrecarga.
Un subconjunto de este tipo de test son las pruebas de resistencia, en donde se sostiene durante un largo periodo de tiempo al uso normal esperado, y se comprueba el comportamiento del sistema.
Así se puede obtener indicadores como el “Tiempo entre fallos”, el “Tiempo medio de fallo” o similares, que permiten realizar acciones preventivas en el futuro.
Test de estrés
El objetivo de estas pruebas es revelar errores y bloqueos en la aplicación cuando es llevada a situaciones de carga alta. Es decir, un gran número de transacciones, de transferencias, de peticiones, de cálculos, etc.
El sistema se estresa llevándolo a los valores máximos esperados en las operaciones en producción, y se mantiene una monitorización constante del hardware y el software para tomar métricas sobre el comportamiento del sistema tanto durante la prueba de carga como en la recuperación del mismo al relajar la prueba de estrés.
Especialmente duras aquellas, en donde se lleva el sistema a superar varias veces su capacidad teórica y esperada - incluso llegando al colapso de la plataforma - durante breves espacios de tiempo. Pudiendo observar y medir cómo se comporta el sistema en esas condiciones, cuales son los subsistemas que primero fallan, de qué forma y cómo se recupera al volver a valores nominales.
Test de capacidad
Como indica su nombre, estas pruebas están centradas en apoyar la planificación de capacidades del sistema.
Partiendo de la base actual, se incrementa la carga del sistema para hallar el punto en donde inicia la degradación del rendimiento. Viendo las métricas se puede realizar una planificación de crecimiento del sistema para poder absorber más carga de trabajo (por ejemplo, incrementar el número o potencia de los procesadores, aumentar el ancho de banda, incrementar la memoria RAM, etc).
También son imprescindibles para poder definir un plan de escalado horizontal o vertical y, con entornos virtual izados, poder hacer pruebas piloto para validar las diferentes hipótesis de crecimiento.
Test de rendimiento
Son aquellas pruebas que validan los Criterios de Aceptación de rendimiento que describen la capacidad de respuesta, velocidad, escalabilidad y estabilidad de la aplicación.
Estas pruebas identifican las discrepancias entre las expectativas de rendimiento y las realmente obtenidas, permitiendo a negocio el tomar decisiones estratégicas sobre las plataformas y que se pueda planificar las acciones necesarias para optimizar las prestaciones de la solución.
Cuándo y cómo integrarlos
Muchos equipos de desarrollo tienen la impresión de que las pruebas de rendimiento se realizan cuando el código está estabilizado y durante los procesos de QA que desembocan en el despliegue. Incluso, en que su sitio natural es más cerca de producción que en construcción.
Pero eso es un error; las pruebas de rendimiento deben estar integradas desde el primer momento en el proceso de construcción de la construcción del software. Incluso antes.
Cuando se está realizando la toma de requisitos o incepción, antes de empezar a tirar una sola línea, durante la redacción de la Pila de Producto, se deben definir las historias, objetivos, y requisitos de rendimiento. Incluso se pueden diseñar los pilotos necesarios para validar las propias pruebas y las medidas que se quieren obtener.
Una vez arrancadas las iteraciones, en conjunto con el resto del equipo, se compromete las historias y requisitos que se van a desarrollar, se construyen las pruebas y los escenarios necesarios, y se realizan los test que puedan aportar valor a la propia construcción.
Durante el proceso de Despliegue se lanzan las pruebas de Aceptación, ten en cuenta que no todos los test están orientados a las validaciones de negocio como hemos visto con anterioridad, y se documentan los resultados . Por último, como momento crítico de toda iteración Agile, se incluye una retrospectiva de rendimiento dentro del proceso general de Mejora Continua.
Como puedes ver, es crítica la integración completa del equipo de test con el resto de los miembros del equipo. Ya que, solamente así, se podrá realizar un desarrollo que tenga el rendimiento como una de sus prioridades, evitando un precioso código de alta calidad que esté por debajo de la eficiencia exigida.
No hay balas de plata
Como bien sabe cualquiera que haya trabajado en desarrollo de software, no existen soluciones únicas que valgan para todas las ocasiones. Y los test de rendimiento también tienen sus ventajas e inconvenientes.
Ventajas
- Incremento de los ingresos al funcionar correctamente el sistema, procesando las transacciones dentro del plazo comprometido.
- Evitar que un problema de rendimiento implique el tener que desechar parte del sistema para ser reconstruido.
- Evitar que un problema de rendimiento implique retrasos en la puesta en producción de una pieza de negocio comprometida.
- Evitar innecesarios costes de adquisición de hardware adicional, a causa de problemas de escalabilidad o rendimiento.
- Evitar el incremento de costes de mantener un software en producción a causa de problemas de rendimiento creciente.
- Reducir el coste de operaciones para la gestión de problemas en el sistema originados por un rendimiento por debajo de las expectativas.
- Identificar cuellos de botella, en el hardware y software, que puedan tener impacto en el rendimiento o escalabilidad a un futuro.
Pero puntualizando a este frio listado, siempre me sorprende la cantidad de errores que suceden cuando sometemos a un código “sólido” - desde el punto de vista de codificación- a pruebas de estrés. Se lanzan los test y van surgiendo errores por muchas causas, pero que empiezan casi siempre por la saturación del pipeline de las comunicaciones vía hhttp request al servidor.
Entre los fallos que te vas a encontrar, puede haber problemas con las sesiones de sql o fugas de memoria (memory leaks) a causa de no utilizar un close o un dispose a tiempo. Porque hoy en día nos apoyamos demasiado en la “magia” del sempiterno recolector de basura.
Otro será un condicional ineficaz, un cuello de botella en un servicio que produce timeout en los casos de carga máxima; un sistema que no se recupera al ser llevado a límite, que no libera la memoria o el procesador y que tiene un límite temporal demasiado estrecho antes de llevar a la infraestructura a sus límites o a un funcionamiento degradado.
Por ello, para mí, la gran ventaja de aplicar pruebas de rendimiento lo antes posible es que se prueban servicios, módulos y plataformas completas. No solamente el hardware, sino también el software, la arquitectura, la escalabilidad y la visión global del desempeño de la aplicación.
Y me aseguro de que todo el esfuerzo y trabajo realizado sea utilizable por los usuarios.
Inconvenientes
El probar el sistema completo, llevándolo a sus límites, implica que requieren un trabajo extra en su planificación, construcción, ejecución y análisis de los resultados.
Además, por la taxonomía de la ejecución, se requiere una gran cantidad de tiempo y la presencia de los desarrolladores. Este tipo de test es muy complicado, o imposible, de integrar en un proceso de integración continua, más allá de los de validación.
De hecho, este tipo de pruebas son parte de la “pieza” de monitorización de las prácticas DevOps, orientadas a la salud de las aplicaciones. Y que se merecen, por si solas, un artículo.
Siendo el mayor inconveniente, la dificultad de transmitir al equipo de negocio y de gestión del proyecto el valor que aporta estas prácticas de aseguramiento de la calidad, y que aprueben el incremento del coste asociado durante la construcción y despliegue a cambio de todas las ventajas referenciadas anteriormente.
Más información
The Forrester Wave™: Application Performance Management, Q3 2016
Fundamentals of Engineering for Performance
Ver todos los comentarios en https://www.genbeta.com
VER 0 Comentario