Pruebas de rendimiento Web para Windows Azure

Una de las preguntas más recurrentes que suele tener los clientes a la hora de trabajar en Windows Azure suele ser, ¿cuál será el rendimiento de mi sitio web en Azure?

La respuesta a esta pregunta no es sencilla o universal. Depende de muchos factores, del tamaño de la máquina utilizado en el servicio en la nube, de la tecnología, cuantas consultas se hagan a la base de datos, ect. El número de factores que pueden determinar ese número final es amplísimo, así que no se puede dar una respuesta para todos los casos.

Entonces ¿cuál es la mejor aproximación para dar respuesta a esa pregunta?

Medir. Medir. Medir.

Pero antes de medir el tiempo que tarda el sitio web en responder, cabe mencionar algunos artículos creados por otros desarrolladores sobre cómo aumentar el rendimiento de las aplicaciones web.

Coding Horror – Performance is a Feature

Scott Hanselman – Penny Pinching in the Cloud: Enabling New Relic Performance Monitoring on Windows Azure Websites

Medir

La mejor manera para saber si una aplicación web es lenta o rápida es medir el tiempo que tarda una respuesta. Esto permite tener una media real de como el sitio web funciona, pero eso no es suficiente. Se necesita además, simular cierta carga, varios usuarios, con varios patrones de uso de la web. Y no solo hacer una sola petición, sino una navegación completa del usuario comprobando cookies, parámetros de la url, inicios de sesión, ect.

Una vez que se ha establecido un escenario base, uno puede empezar a realizar optimizaciones en su código para ver cómo se mejora ese tiempo. Es importante realizar estas mediciones en el rendimiento una vez que se ha realizado el sitio web, o por lo menos cuando está a punto de cerrarse el proyecto. No tiene ningún sentido empezar a hacer optimizaciones tempranas, ya que son un anti patrón muy claro.

Premature-Optimization and Performance Anxiety

Performance anti patterns

Visto todo lo anterior, lo ideal sería disponer de algún software que nos permite grabar la navegación de un usuario y que después sea capaz de volver a simular todos los pasos que ese usuario ha hecho. Justamente estamos hablando de los Web Performance Load Test de Visual Studio Ultimate.

Web Performance and Load Test

Visual Studio en su versión Ultimate, incluye un tipo de proyecto dentro de la categoría de Test llamado Web Performance and Load Test, que permite grabar sesiones web.

clip_image002

Cuando se ha creado el proyecto, hay un fichero con extensión de tipo .webtest donde aparecerán todas las peticiones HTTP que se han grabado para esa sesión. Cada fichero representa una colección de peticiones HTTP que pueden ser una historia de usuario, una navegación sobre una característica a medir, o simplemente una invocación a una API Rest.

clip_image004

Se puede hacer una grabación con Internet Explorer donde se registran todos los pasos que el usuario ha hecho en el sitio web.

clip_image005

clip_image006

Una vez que ha terminado de hacer la grabación aparecerán en Visual Studio la lista de Urls a testear.

También se puede utilizar un origen de datos para obtener las urls y así hacerlos parte un test de integración.

Por supuesto se pueden agregar a mano las peticiones, las condiciones para dar como válida una petición y todo lo relacionado con el ciclo de vida de una petición.

clip_image008

Una vez que se ha confeccionado la lista de las Urls que forman parte del test, se puede pasar a hacer la prueba de rendimiento o se puede personalizar las peticiones. Hay un botón en la barra del test que permite generar el código en C# asociado de las peticiones para poder modificarlo a petición del usuario, de esta manera se puede automatizar mucho más el proceso.

clip_image010

Prueba de carga

El siguiente paso es generar y configurar una prueba de carga para la prueba web recién creada. Dentro del proyecto de Test hay que pulsar en añadir nuevo elemento y seleccionar prueba de carga (Load Test).

clip_image012

En el cual inmediatamente creará un asistente en el que se pueden configurar las diferentes opciones para la prueba de carga.

clip_image014

1. Darle un nombre al escenario

clip_image016

2. Ahora se seleccionan el patrón de carga, como se desean simular los usuarios de la prueba. Se puede elegir un valor constante de usuarios y otro incremental en el que se pueden configurar todas las opciones de incremento.

clip_image018

3. En la siguiente pantalla se puede elegir la manera en la que se mezclan los diferentes escenarios de prueba (que son las pruebas web que se han definido antes).

clip_image020

4. En esta pantalla es donde se agregan los diferentes test que se van a formar parte de las pruebas y que tanto porciento representan.

clip_image022

5. Ahora se pueden seleccionar las velocidades de red para calcular el tiempo de descarga.

clip_image024

6. Mezcla de navegadores

clip_image026

7. Ahora se pueden seleccionar las máquinas de las que se quieren obtener los contadores de rendimiento, en el caso que se está tratando ahora (Windows Azure) tendríamos que abrir los puertos de WMI para poder acceder a esa información, pero si se está haciendo una prueba en local con otra máquina se puede poner el nombre de la máquina y qué contadores de rendimiento se quieren monitorizar.

clip_image028

8. La última opción define cuánto tiempo durará la prueba.

clip_image030

Por supuesto todas estas opciones pueden ser modificadas posteriormente en cualquier momento. Una vez finalizado el asistente, en Visual Studio aparece esta pestaña que contiene las propiedades del proyecto de carga

clip_image032

Recopilando datos

La prueba de carga consiste en recopilar datos de muchos contadores, no solo de las máquinas en las que se ejecuta la web, sino de los agentes que ejecutan las pruebas de cargas. Eso hace que una de las opciones a la hora de guardar las muestras de la prueba sea una base de datos SQL Server. Desde la opción de administrar el controlador de la prueba, se puede acceder al almacén donde se guardarán los datos.

clip_image033

Desde aquí se puede configurar en qué instancia de SQL Server se guardaran los datos de muestra. La base de datos tiene que tener un esquema predeterminado para que funcione correctamente. En el directorio de instalación de Visual Studio hay un fichero llamado (C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE) loadtestresultsrepository.sql que contiene el script necesario para generar la base de datos desde cero.

Ejecutando la prueba

Una vez que se ha configurado todas las opciones de la prueba de carga, se puede proceder a ejecutar la prueba. Visual Studio ofrece un panel de control para ver toda la información sobre la prueba, los contadores y los resultados de manera provisional. Toda la información que se recopila se guarda en la base de datos antes configurada y se puede volver a abrir para consultar los datos.

Panel de información

Cuando se ha acabado la prueba y se vuelve a abrir el resultado, primero aparece un resumen de todo lo ejecutado.

image

Donde se puede visualizar información relativa a cuando se ha ejecutado la prueba, los principales valores del resultado; carga de usuarios, media de tiempo de respuesta de la web, número de peticiones por segundo, ect.

Además de esta información, se puede visualizar individualmente por cada una de las web que forman parte de la prueba, la información del número de peticiones y de tiempo medio de respuesta.

Al final de todo aparece el detalle del controlador y de los agentes que han realizado la prueba.

Graficas

Otra pestaña muy importante para entender los resultados de la prueba de carga es la de gráficas. En esta pestaña se puede visualizar, a lo largo del tiempo, los valores que se deseen. De manera predeterminada Visual Studio ofrece un cuadrante de cuatro gráficas, donde se pueden añadir métricas sobre las diferentes opciones de la prueba de carga.

image

Conclusión

Con las pruebas de carga Web de Visual Studio se pueden hacer mediciones del tiempo medio de respuesta de los sitios web, numero de excepciones, número de peticiones por segundo antes de dar un error de ocupado, ect.

De esta manera se puede hacer una prueba de carga directamente apuntando a Windows Azure, para ver cuantas peticiones son capaces de responder los servidores antes de dar errores 500. Es importante hacer estas pruebas con el número de servidores que se utilizará en producción para intentar que el entorno de pruebas de carga sea lo más similar al entorno final.

Luis Guerrero.

@guerrerotook

12 Horas de Visual Studio – Calidad de Software y patrones de diseño en Windows Phone 7.5

Hoy es el evento de 12 Horas de Visual Studio de Microsoft y Globbtv, podeis ver el evento en directo aquí http://www.globbtv.com/vstudio12horas/

Este es el material que voy a utilizar sobre mi charla sobre “Calidad de Software y patrones de diseño de Windows Phone 7.5”

clip_image002

El código de ejemplo os lo podéis descargar de aquí, http://bit.ly/12HorasVSWindowsPhone

Como generamos las releases en Plain Concepts, el caso de las aplicaciones de Windows Phone de Prisa.

Como generamos las releases en Plain Concepts, el caso de las aplicaciones de Windows Phone de Prisa.

Como dije anteriormente en mi artículo, ya están disponibles las aplicaciones de El País, As.com y CincoDías.com en el Marketplace de Windows Phone 7. Estas aplicaciones han sido desarrolladas y diseñadas íntegramente por Plain Concepts, en este artículo explicaré cuales son los procesos de desarrollo que seguidos dentro de PlainConcepts para asegurar la calidad de la aplicación y las técnicas empleadas.

Las aplicaciones están desarrolladas en C# usando Visual Studio 2010 y la metodología usada es Scrum, adaptándola para el desarrollo con un equipo tan pequeño y a las particularidades del proyecto en cuestion. Durante su desarrollo han participado un equipo de dos programadores, un diseñador y un scrum master. Se han empleado 7 iteraciones a aproximadamente 2 semanas cada una para completar el desarrollo, más una iteración final para estabilizar código. Durante la penúltima y última iteración una persona fuera del equipo se encargó del testing en la aplicación en dispositivos físicos.

Aquí os muestro la gráfica de Burndown and Burn Rate del proyecto:

clip_image002

Como se puede ver, conforme se iban generando trabajo se iba completando y aunque hay muchos picos, que indican que se ha ido bajando las horas de las tareas adecuadamente, en general la progresión de la aplicación ha sido buena. Conforme se iba cerrando trabajo se iba generando nuevo. La banda de color azul de fondo indica tareas que se quedaron fuera de la funcionalidad final de la aplicación, pero que no se eliminaron del TFS.

La gráfica del estado de todas las iteraciones, muestra cómo se fueron cerrando las tareas de cada iteración de manera correcta. Además podemos observar como al principio el equipo era demasiado optimista en cuanto a las estimaciones que se hacían, pero conforme las iteraciones fueron avanzando la confianza, la experiencia y el mayor conocimiento del proyecto hacen que las estimaciones y el reparto de tareas sean cada vez más cercanas a la realidad. Aunque como he dicho se iban generando tareas fuera de la iteración con trabajo de fondo que no se fueron cerrando en el TFS.

clip_image004

Como está el proyecto organizado

Al desarrollar una aplicación en Silverlight para Windows Phone 7, el patrón principal a la hora de desarrollar todas la aplicación ha sido MVVM, este patrón permite tener una vista hecha en xaml sin apenas nada de código y llevarse toda la lógica de la aplicación al ViewModel donde se realizaba todo el trabajo, en este desarrollo no se ha usado ningún framework de terceros para MVVM ya nosotros mismo hemos generado las utilidades que necesitábamos para el proyecto en un proyecto común a las 3 aplicaciones. Así el diagrama de arquitectura general se queda así:

clip_image006

Donde PlainConcepts.Common está la funcionalidad común a los tres proyectos; convertes, controles, tipos de datos comunes, parseadores de xml, navegación, serialización, comandos y viewmodels.

En cada uno de los proyectos están sus respectivas vistas, controles de usuario, páginas del teléfono y demás artefactos específicos, imágenes, iconos, etc.

Configuración del TFS, políticas de check-in, ramas y builds.

Para manejar el ciclo de vida del desarrollo y la integración continua durante el proyecto se han usado diferentes artefactos para asegurar que el desarrollo era incremental.

Políticas de check-in

El proyecto tenia habilitado el multiple chech-out y como políticas de check-in teníamos, requerir asocial un work ítem en cada check-in y requerir agregar un comentario en cada check-in. Eso nos permite tener trazabilidad de como el proyecto se ha desarrollado y que changeset del servidor está asociado a cada work ítem. Por no decir que también de esta manera sabemos que work ítems están asociados a cada compilación.

Políticas de ramas (branching)

Durante el desarrollo inicial de la aplicación no había ninguna configuración especial en el servidor sobre ramas, es decir únicamente teníamos una rama dev (Developer) en la que se trabajaba. Pero conforme el cliente fue pidiendo versiones estables para ver el progreso del desarrollo, se optó por esta configuración:

clip_image007

La carpeta dev se pasó a llamar Main. A partir de esta rama Main se generaron, dev y todas las releases de las diferentes aplicaciones.´

Esto nos permitía tener en la rama Main versiones estables de las tres aplicaciones entregables al cliente, libre de bugs, estabilizadas y fuera del ciclo de desarrollo. El tener una rama Main te permite que el equipo de desarrollo siga trabajando en dev, pero conforme la funcionalidad vaya generándose que se vayan mezclándose (merge) la funcionalidad de dev a Main y así hacer un entregable al cliente.

Las ramas de reléase de cada aplicación tienes las versiones reléase publicadas en el Marketplace y las sucesivas actualizaciones que se vayan generando. Así si encontramos un bug en la versión del servidor, tenemos el changeset etiquetado podemos generar un fix en la rama reléase de esa aplicación, sin tener que impactar en las demás aplicaciones y cuando el bug este corregido y testeado, propagar ese cambio de la rama reléase de la aplicación, a la rama Main y de ahí a dev y el resto de releases (en caso de que el bug sea de algo común).

Compilaciones (Builds)

Otra requisito importante para seguir integración continua durante el desarrollo son las compilaciones, en el proyecto hay 5 compilaciones creadas y todas ellas activas.

  • As Release 1.0: gated checking en la rama de release (modo release).
  • CincoDias Release 1.0: gated checkin en la rama de release (modo release).
  • ElPais Release 1.0: gated checkin en la rama de reléase (modo release).
  • Prisa.WP7: continuous integration en la rama de dev (modo debug y release).
  • Prisa.WP7 Main: gated checkin en la rama de main (modo debug y release).

Con esta lista de compilaciones en el equipo nos podíamos asegurar de que cada checkin era incremental, porque podíamos verificar que la compilación era correcta por lo menos en Main y en las ramas de release. Esto nos permitía saber que el código que teníamos en Main y Release compilaba sin problemas para que en cualquier momento se pudiera hacer un cambio, además de eliminar el molesto “Works on my machine” ayudando así a los tester a tener versiones incrementales de la funcionalidad compilada por el servidor y poder ir generando bugs sobre las versiones generadas.

Aquí podemos ver el estado de las compilaciones correctas a través del tiempo:

clip_image009

Otra de las cosas interesantes de tener un servidor de compilaciones es que conforme la funcionalidad va generándose se van generando binarios de la aplicación que se pueden consumir, así que el equipo de Plain Concepts decidió dar acceso al cliente, a través de http a la carpeta de salida de todos los binarios de las aplicaciones. De esta manera el cliente puede tener acceso ubicuo a su producto y desplegarse la última versión siempre que lo desee.

Testing

Aunque no es posible integrar el testing de Visual Studio en proyecto de Silverlight para Windows Phone 7, el testing de la aplicación se definió como tesing manual que se hacía por personas independientes del proyecto en terminales físicos y nunca sobre el emulador, con conexiones 2G (GPRS), 3G, 3.5G y WiFi, sobre varios terminales diferentes.

Como se publica una versión en el Marketplace

El proceso para publicar una versión en el Marketplace implica tener los cambios solicitados por el cliente en la rama reléase de la aplicación, que la compilación en modo reléase, desplegar esa fichero generado por el servidor de compilación en el teléfono y testear que todos los cambios que el cliente había solicitado están integrados y que de la lista de test previos que todo este correcto, para que se no se no se hayan introducido nuevos bugs.

Una vez hecho esto tenemos que subir el número de versión de la aplicación y hacer checkin, este último check-in con el cambio de versión, es el xap que se sube al Marketplace. Se etiqueta la build con una etiqueta de calidad “Published in WP7 Marketplace” y se retiene la build.

clip_image011

Además de eso se aplica una etiqueta en la rama de la aplicación con la versión de la aplicación para en caso de que haya un bug saber el changeset asociado.

Conclusiones

El desarrollo de software es una disciplina muy complicada y que no se debe infravalorar, en Plain Concepts nos gusta hacer las cosas bien y sabemos lo complicado que es montar un proyecto, mantenerlo y sobre todo desarrollar funcionalidad. Así que con este post queremos mostrar un poco cual es el proceso que seguimos internamente para desarrollar. Eso no significa que todos los proyectos se montan de la misma manera, sino que cada proyecto es único a la hora de crearse y desarrollarse, y no existen reglas fijas de metodologías y artefactos que utilizar. Estas deben ser adecuadas al proyecto en cuestión haciendo que sean útiles para el equipo y para el proceso en sí. Lo difícil de todo esto es saber que metodologías usar, que tecnologías usar y cómo gestionar todo ese flujo. Como dice Rodrigo Corral, “los proyectos no fracasan por la solución tecnológica, sino por la gestión en sí”, es decir, que confiar en que el proyecto va a ser un éxito simplemente por usar todas las últimas tecnologías y herramientas, es simplemente un error, porque no te elimina la necesidad de gestionar personas y recursos.

Si tenéis alguna pregunta, o queréis comentar algo sobre el proceso podéis hacerlo en los comentarios.

Saludos.

Luis Guerrero.