RENDIMIENTO ÁGIL

Introduciendo Ingeniería de Rendimiento dentro de un desarrollo ágil

Sergio Fernández (@artabricus)

"- Podría funcionar. 
- ¿´Podría´? Tenemos que lograr algo mejor que un ´podría´."

Origen (2010)

 

En esta entrada del blog me gustaría abordar las implicaciones de una situación con la que me he encontrado, muy a menudo, (incluso) en proyectos muy bien planteados desde la perspectiva metodológica y con una buena definición funcional. En estos proyectos al abordar las últimas etapas de la vida del producto (muchas veces ya con varias subidas a producción hechas) se encuentran con alguna de estas situaciones:

  • Aparecen problemas de rendimiento en las UAT.
  • Llega el momento de pasar a producción y se desconoce cual es el hardware adecuado y necesario.
  • Ciertos procesos tardan tanto tiempo que parecen estar "colgados".
  • Los usuarios se "desesperan" con los tiempos de respuesta de la aplicación.
  • Se desconoce el impacto en el rendimiento de la inclusión de una nueva funcionalidad.
  • Etc...

De hecho estas situaciones, o mas bien síntomas, se pueden resumir en LA pregunta:

¿Como se gestiona que el sistema/producto a ser desarrollado tendrá un rendimiento adecuado?

Si no existe una respuesta a esta pregunta es que el proyecto carece de una estrategia de rendimiento dentro del ciclo de vida de desarrollo.

 

Probablemente, antes de acometer una propuesta metodológica para dar respuesta a esta cuestión existe una pregunta previa a ser respondida: ¿Que es rendimiento?. Desde mi perspectiva el rendimiento podría definirse como la percepción del usuario de la calidad de servicio ofrecida por un sistema o un producto. En general se refiere a rendimiento todo aquello relacionado con capacidad, objetivos de sistema y gestión de sobrecargas.

Se podría denominar Ingeniería del Rendimiento a todas aquellas actividades dentro del ciclo de vida de desarrollo enfocadas a resolver todas las necesidades relacionadas con estos aspectos. Las actividades fundamentales serán:

  • Realizar las definiciones necesarias para poder estudiar el rendimiento de los sistemas: Targets, Pruebas de aceptación, Política de overload, etc.
  • Crear y planificar los instrumentos necesarios para alcanzar el rendimiento definido: Budgets, Arquitectura de overload, etc.
  • Seguimiento de las actividades.

 

Aunque las actividades relacionadas con la Ingeniería de Rendimiento son aplicables a cualquier tipo de Metodología, centraré este articulo en su uso en metodologías ágiles, y en particular en Scrum. En metodología Scrum es necesario que algún miembro del equipo lidere estas actividades, adquiriendo un role de "Ingeniero/Experto en Rendimiento". En general, existirá un único líder de estas actividades, compaginando normalmente estas con otras actividades como desarrollo o diseño, y múltiples miembros del equipo (sino todos) deberán realizar distintas actuaciones relacionadas con las actividades de Ingeniería de Requisitos. Será tarea del Scrum Master la facilitación de todas estas actividades como una más de la ejecución del proyecto. La información básica a manejar desde el punto de visto de la Ingeniería de Rendimiento es la siguiente:

  • Targets (asociados a las historias de usuario).
  • Budgets (asociados a las actividades de arquitectura/diseño).
  • Estimaciones (asociados a las actividades de desarrollo).
  • Medidas (asociadas a las pruebas).

 

Buscando el rumbo 

Los Targets consisten en la especificación del "que" es necesario desde el punto de vista de los requisitos de rendimiento y será el Product Owner el encargado normalmente de definir esta información. En Scrum los targets no pueden describirse como Historias de Usuario en sentido estricto, personalmente, como Product Owner, considero que es mejor incluirlos como parte del Definition of Done general del proyecto. Otra posibilidad es incluir estos targets como Product Backlog Items (PBIs) que no se incluirán en ningún Sprint, aunque esta aproximación es mas complicada de tracear. Los Targets, generalemente, serán de varios tipos:

  • Capacidad/Carga.
  • Tiempos de respuesta.
  • Sobrecarga.
  • Escalabilidad.

Es una tarea imprescindible el que los Targets estén acordados con los usuarios, clientes y con el equipo (por ejemplo, puede resultar muy interesante proponer un Taller de Rendimiento durante la fase de Inception). Habitualmente los usuarios serán incapaces de definir cuales son las características que requieren para su sistema, por lo que será una actividad específica a realizar por parte del Product Owner una vez se hayan entregado las primeras entregas de producto, demostraciones del rendimiento sobre todo en lo que refiere a Tiempos de Respuesta, a efectos de ir definiendo y refinando poco a poco estos valores. 

Aunque podría pensarse que esta información debería compartirse a través de algún panel físico, en la práctica resulta más efectivo hacerlo a través de una herramienta de cálculo  (spreadsheet) compartida entre todos los miembros del equipo a través de alguna solución software. Esto se debe a la complejidad de los cálculos a realizar para obtener muchos de estos valores y también para poder hacer un seguimiento sencillo de los cambios.

 

Diseño de Budgets 

A lo largo del proceso de ejecución (empezando habitualmente en la fase de Inception) se definirá la arquitectura de la solución a implementar. Cuando esta arquitectura se va refinando, posibilitará la realización de las primeras estimaciones de cual puede ser la capacidad en términos de rendimiento de la arquitectura que se va a implementar. Estos Budgets irán refinándose a lo largo de la ejecución del proyecto en los distintos Sprints y afinandose en función de los datos provenientes de la implementación y las pruebas.

El punto realmente relevante de los Budgets es que las personas que están trabajando en la arquitectura y el diseño de la aplicación no se centren únicamente en las posibilidades funcionales de la misma, sino que se contemple igualmente las necesidades en términos de rendimiento (Targets) establecidas.

Existirán diversos tipos de Budgets a definir en función de los requisitos establecidos:

  • CPU Budgets.
  • Disk Throughput.
  • Capacidad de la Base de Datos/Conexiones.
  • Otros.

Estos Budgets deberán condicionar decisiones de arquitectura como el diseño y política de caches, tamaños de las colas, multithreading, clusters, multiprocesos, etc. La gestión de situaciones de sobrecarga u overload deben ser acometidas como parte de este ejercicio (tanto la detección del overload como la gestión del mismo).

 

Durante la fase de ejecución o de implementación puede ser interesante realizar una actividad de Estimación del rendimiento del producto que se está realizando. Aunque existen algunos motivos para realizar este esfuerzo, esta es sin duda la actividad mas prescindible dentro de las actividades de Ingeniería de Rendimiento sobre todo si está utilizándose metodología Scrum. Esto se debe a las pruebas tempranas que se realizan en la metodología ágil, por lo que el esfuerzo para hacer esta estimación produce poco beneficio con respecto a los datos reales obtenidos durante las pruebas del Sprint. En todo caso las estimaciones podrían ayudar a detectar algunos riesgos y a verificar las soluciones a ser implementadas, sobre todo, si por algún motivo, no se pudieran ejecutar las pruebas de rendimiento durante el Sprint en curso.

 

Continuando con la aproximación ágil, la siguiente fase si es una de las fundamentales dentro de todo este proceso y es el de la Medición, hasta ahora en los Targets se han definido que objetivos se han de alcanzar (que vamos a medir), en los Budgets se ha trabajado en como alcanzar estos objetivos y finalmente el resultado de este proceso debe medirse para lograr establecer la situación real, estudiar esta información y planificar las acciones necesarias en el proceso para intentar aproximarse a los Targets definidos (o la viabilidad de los mismos).

Típicamente se realizarán medidas de:

  • Consumo de recursos: CPU, Memoria, Red, Disco, etc.
  • Tiempos: De respuesta, de arranque, de ejecución, etc.
  • Arquitectura: Tamaños de las colas, utilización de los pools, número de threads, número de procesos, etc.

Estas mediciones deberán hacerse como parte de las tareas de ejecución del Sprint, siendo necesario construir los entornos o las herramientas necesarias para automatizar estas ejecuciones en los Sprints iniciales o durante la fase de Inception. El miembro del equipo con el role de Ingeniero de Rendimiento deberá definir cuales serán las medidas necesarias y definirá, en base a los Targets establecidos, los escenarios y pruebas a construir para obtenerlas. Será importante no obviar escenarios típicos como la toma de medidas antes y después de una situación de overload o tras un periodo largo de actividad del sistema con una carga de trabajo sostenida.

También será su responsabilidad el compartir los resultados con el equipo en la finalización de cada Sprint y la dirigir la discusión sobre las acciones necesarias a realizar para intentar alcanzar los objetivos. Es muy interesante genera un panel Kanban similar al que se suele utilizar para los riesgos del proyecto para incluir todas las acciones a acometer relacionadas con el rendimiento.

 

 

Estos pequeños conceptos de Ingeniería de Rendimiento podrán ser un buen punto de partida para todos aquellos proyectos donde existan importantes (o no tanto) exigencias de calidad de servicio por parte de los usuarios del producto. Como mínimo deberían constituir un planteamiento a realizar dentro de las Inceptions de los proyectos ágiles, donde los participantes en el proyecto han de plantearse cuales son las expectativas que se tienen del sistema a crear en términos de rendimiento (no solo de funcionalidad) y comenzar a definir los roles y las actuaciones necesarias para alcanzar esas expectativas.

 

 

Referencias


[Hesselgrave 1998] Mary Hesselgrave, "Avoiding the Software Performance Crisis". WOSP '98 Proceedings of the 1st international workshop on Software and performance. Pages 78-79.

[Cohn 2008] Mike Cohn. "Non-functional Requirements as User Stories". http://www.mountaingoatsoftware.com/blog/non-functional-requirements-as-user-stories