Un cliente, como siempre, me ha preguntado cómo puede medir el desempeño de los Web Services que piensa Construir utilizando DotNet.
Le escribí el siguiente mail, para que pueda usarlo como una guía para hacer mediciones.
¿Cómo funcionan los Web Services?
La arquitectura de los Web Services [1] está basada en la infraestructura ASP.NET y usa serialización XML [2]. Cuando un el servidor Web procesa una requerimiento HTTP para un Web Services, Internet Information Server (IIS) [3] mapea la extensión (.asmx) a la interfaz de programación de aplicaciones Internet Server (ISAPI) [4] de ASP.NET (Aspnet_Isapi.dll). Está ISAPI entonces envía el requerimiento al proceso de trabajo de ASP.NET, donde entra en el Pipeline de procesamiento de requerimientos, el cual es contralo por el objeto HttpRuntime [5]. Esto se muestra en el diagrama 1.
Diagrama 1: Arquitectura ASP.NET Web Services y flujo de requerimientos
El requerimiento pasa inicialmente por el objeto HttpApplication [6], seguido por la serie de objetos HttpModule [7] registrados. Los objetos HttpModule son registrados en el archivo de configuración Machine.config o en la sección <httpModules> del Web.config de cada Servicio Web. Los objetos HttpModule son los responsables de manejar los aspectos como autentificación, autorización, Caching y otras tareas trasversales.
Luego de pasar el requerimiento a través de los módulos HTTP en el Pipeline, el objeto HttpRuntime verifica con el administrador Webservicehandlerfactory [8] que la extensión .asmx esté registrada. Este crea una instancia del administrador HTTP que es responsable de procesar el requerimiento al Web Services. Este administrador (Handle) deriva de WebServicesHandler [9]. El administrador HTTP usa reflexión (Reflection) [10] para trasformar el mensaje SOAP en invocaciones a los métodos del Web Services.
Medidas de desempeño para Web Services
Para determinar de manera efectiva el desempeño de Web Services en DotNet es necesario poder medir los siguientes aspectos:
-
Throghput: Medida de la cantidad de requerimientos ejecutados por segundo y cuellos de botella relativos al Throghput, como el número de requerimiento en espera de ser ejecutados y el número de requerimientos que se están rechazando.
- Cost of throghput: Medida del uso de procesador, memoria, I/O de disco y utilización de red para responder a los requerimientos que se están ejecutando.
- Request Execution Time: medida del tiempo que toma la ejecución de un método del Web Services en el servidor.
- Latency: Medida del tiempo que toma la ejecución y llegada de la respuesta al cliente de un requerimiento al Web Services.
- Cache utilization: Medida de la razón entre Cache Hits y Cache misses. Esto necesita ser visto en un contexto amplio porque el uso de memoria virtual afecta el desempeño del cache.
- Error and Exception: medida del número de errores y excepciones generadas.
- Xml Serialization: Mide el costo de la serialización de XML, muy importante en los Servicios Web.
¿Cómo medir?
Como los Web Services son un caso particular de ASP.NET es necesario aclarar primero como medir desempeño en ASP.NET. Para esto es necesario preliminarmente utilizar la herramienta Performance Counter [12].
El siguiente diagrama 2 muestra el ciclo de vida de los requerimientos en ASP.NET.
Diagrama 2: Ciclo de vida y medidas para un requerimiento ASP.NET
Throughput
-
ASP.NET Applications\Requests/Sec
Umbral: depende de la lógica de negocio.
Significado: es uno de los primeros indicadores que se usan para calcular la capacidad necesaria para el sistema.
-
Web Service\ISAPI Extension Requests/sec
Umbral: depende de la lógica de negocio.
Significado: La tasa de requerimientos a la ISAPI que se están procesando simultáneamente. Este contador no es afectado por los Work process que se reinician como si lo es ASP.NET Applications\Requests/Sec.
Cost of Throughput
El costo del throughput es la medida del uso de procesador, memoria, I/O de disco y utilización de red para responder a los requerimientos que se están ejecutando. Esto no es específico a los Web Servies ni ASP.NET. Pueden verse los indicadores en detalle en el capítulo 15, sección System Resource [11].
Request
-
ASP.NET\Requests Current
Umbral: No tiene un valor específico.
Significado: Número de requerimientos que está manejando la ISAPI, incluidos encola, ejecutándose y esperando a escribir en el cliente. ASP.NET comienza a rechazar requerimientos cuando el contador excede el número definido en requestQueueLimit.
-
ASP.NET Applications\Requests Executing
Umbral: No tiene un valor específico.
Significado: Número de requerimientos que se están ejecutando. El objeto HttpRuntime controla este contador, incrementándolo cuando atiende un nuevo requerimiento y disminuyéndolo cuando terminar de procesar el requerimiento.
-
ASP.NET Applications\ Requests Timed Out
Umbral: No tiene un valor específico.
Significado: Cantidad de requerimientos que dieron TimeOut y no se ejecutaron.
Queues
-
ASP.NET\ Requests Queued
Umbral: No tiene un valor específico.
Significado: Cantidad de requerimientos actualmente en colas. Los requerimientos encolados tienen un límite fijado por configuración en el parámetro requestQueueLimit que tiene como límite por defecto 5.000.
-
ASP.NET Applications\ Requests In Application
Umbral: No tiene un valor específico.
Significado: Cantidad de requerimientos actualmente en cola para cada directorio virtual, que es el equivalente a una aplicación. Estos requerimientos encolados tienen un límite fijado por configuración en el parámetro appRequestQueueLimit , cuando es superado este límite retorna el mensaje "Server Too busy".
-
Queue ASP.NET\ Requests Rejected
Umbral: No tiene un valor específico.
Significado: representa el número de requerimientos rechazados porque la cola de requerimientos está llena. ASP.NET Work Process comienza a rechazar requerimientos cuando sobrepasa el límite configurado en requestQueueLimit la medida ASP.NET\ Requests Queued.
-
ASP.NET\ Requests Wait Time
Umbral: 1.000 milisegundos, El promedio debe tender a cero segundos de tiempo de espera en la cola de requerimientos.
Significado: representa el tiempo de espera del último requerimiento en la cola Name Pipe entre IIS y el Work Process ASP.NET. Esta medida no incluye ningún otro tiempo de espera.
Response Time and Latency
El tiempo de respuesta y la latencia pueden ser medidos desde la perspectiva del cliente o del servidor. Del lado del cliente, se puede medir el tiempo desde que llega el primer y el último byte de la respuesta. La latencia en este caso incluye la latencia de la red (tiempo que agrega la red) y la latencia del servidor (tiempo que toma el servicio en responder al requerimiento). La medida del primer Byte se llama TTFB y la del último TTLB y se pueden capturar con herramientas como ACT [13].
En el lado del cliente es posible medir el tiempo de ejecución de un requerimiento utilizando el contador ASP.NET\Request Execution Time. El diagrama 3 muestra las principales componentes necesarias para estas medidas.
Diagrama 3
-
TTFB
Umbral: Depende del tipo de requerimiento.
Significado: Tiempo que pasa entre el envío del requerimiento y la recepción del primer Byte de la respuesta.
-
TTLB
Umbral: Depende del tipo de requerimiento.
Significado: Tiempo que pasa entre el envío del requerimiento y la recepción del último Byte de la respuesta.
-
ASP.NET\Request Execution Time
Umbral: Depende del tipo de requerimiento.
Significado: Tiempo que se tomó la ejecución del último requerimiento procesado.
Cache Utilization
-
ASP.NET Applications\Cache Total Entries
Umbral: no tiene un valor específico.
Significado: este contador muestra la cantidad de elementos en el cache, tanto internos como externos. ASP.NET usa el chache para almacenar objetos que son caros de crear por ejemplo objetos de configuración.
-
ASP.NET Applications\Cache Total Hit Ratio
Umbral: Con memoria suficiente normalmente se debe tener sobre el 80%.
Significado: este contador muestra las llamadas al Cache tanto internas como externas.
Loading
-
.NET CLR Loading\ Current appdomains
Umbral: el valor debe ser el mismo que el numero de aplicaciones Web más uno.
Significado: el número de Appdomains cargados en el proceso.
-
.NET CLR Loading\ Current Assemblies
Umbral: No tiene un valor específico.
Significado: el número de Assemblies cargados en el proceso.
Worker Process Restarts
-
ASP.NET\ Worker Process Restarts
Umbral: No tiene un valor específico.
Significado: el número de veces que se recicla al aplicación Web y el Work process.
Xml Serialization
Cuando se serializa y se hidrata un objeto, proceso inverso, es posible calcular el costo de estas acciones en términos del uso de memoria y el tamaño de la data. Para esto se puede utilizar el siguiente código de ejemplo [11].
using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Text;
using System.Data;
//A sample class for serialization
public class MyClass
{
public string name;
public string surName;
public MyClass()
{
name = "FirstName";
surName = "LastName";
}
}
class Class1
{
private static long startMemory, endMemory, gcMemory, actualMemory,
overHeadMemory;
private static double percentOverhead;
static void Main(string[] args)
{
//stream to which the class object shall be serialized
Stream fs = new FileStream("SomeFile.txt", FileMode.Create);
MyClass mc = new MyClass(); XmlSerializer xs = new XmlSerializer(typeof(MyClass));
XmlWriter writer = new XmlTextWriter(fs, new UTF8Encoding());
// Clean up the GC memory and measure the measuring as the baseline before
// performing the serialization
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
startMemory = System.GC.GetTotalMemory(false);
xs.Serialize(writer, mc);
//Calculate the overhead and the amount of data after serialization
CalculateOverhead(fs.Position);
DisplayInfo();
writer.Close();
fs.Close();
Console.ReadLine();
}
public static void CalculateOverhead(long streamPosition)
{
endMemory = System.GC.GetTotalMemory(false);
gcMemory = endMemory – startMemory;
actualMemory = streamPosition;
overHeadMemory = gcMemory – actualMemory;
percentOverhead = ((double)(overHeadMemory * 100)) /
(double)actualMemory;
}
public static void DisplayInfo()
{
Console.WriteLine("Total amount of data after serialization ->" + actualMemory);
Console.WriteLine("Total memory used by GC for serialization ->" + gcMemory);
Console.WriteLine("Overhead memory used serialization ->" + overHeadMemory);
Console.WriteLine("Percent overhead ->" + percentOverhead);
}
}
Código 1: Serialización
Referencias
- Web Serices, http://en.wikipedia.org/wiki/Web_services
- Serialización XML, http://msdn2.microsoft.com/es-es/library/90c86ass(VS.80).aspx
- Internet Information Services, http://es.wikipedia.org/wiki/IIS
- ISAPI, http://en.wikipedia.org/wiki/ISAPI
-
HttpRuntime (Clase) ,
http://msdn2.microsoft.com/es-es/library/system.web.httpruntime(VS.80).aspx
-
HttpApplication ,
http://msdn2.microsoft.com/es-es/library/system.web.httpapplication(VS.80).aspx
- HttpModules, http://msdn2.microsoft.com/en-us/library/zec9k340(VS.71).aspx
-
WebServiceHandlerFactory Class,
http://msdn2.microsoft.com/en-us/library/system.web.services.protocols.webservicehandlerfactory.aspx
-
Securely Implement Request Processing, Filtering, and Content Redirection with HTTP Pipelines in ASP.NET,
http://msdn.microsoft.com/library/default.asp?url=/msdnmag/issues/02/09/httppipelines/
- Reflection (computer science), http://en.wikipedia.org/wiki/Reflection_(computer_science)
-
Improving .NET Application Performance and Scalability,
-
Working with Performance Counters,
http://www.microsoft.com/technet/prodtechnol/acs/reskit/acrkch10.mspx
-
Microsoft Application Center Test,
http://msdn2.microsoft.com/en-us/library/aa287410(VS.71).aspx
Excelente post, Jotapé!!
Todos estos temas entran dentro de un concepto conocido como Health Modeling que es, si se quiere, una etapa del ciclo de vida del desarrollo de software (SDLC) donde se determinan estos umbrales que vos destacabas puntualmente para las aplicaciones ASP.NET
La ventaja de incorporar esta etapa del "modelado de la salud" de la aplicación es que permitirá luego, en ejecución, monitorear cómo se está comportando para poder anticipar las tormentas por venir (o, dicho en criollo, cuál servidor se va a empezar a watear)
Quisiera agregar a tu completísima lista sobre medición de rendimiento en aplicaciones ASP.NET, los siguientes
-Health Modeling: A Key Step to DSI-Enabled Applications
http://www.microsoft.com/business/dsi/designwp.mspx
Un paper genérico en modelado de salud de aplicaciones que comenta también una herramienta (sig. link) para definir umbrales personalizados (del tipo "no quiero que el servicio web de confirmación del envío se demore más de x segundos")
-Microsoft Management Model Designer
http://www.microsoft.com/downloads/details.aspx?FamilyID=0ae2caf8-5676-4b57-8945-bdb5b5b55ca0&DisplayLang=en
La herramienta de la que comentaba recién. Permite exportar los modelos a System Center Operations Manager 2007 (un monitor que captura los eventos que las aplicaciones lanzan y si los umbrales no se están cumpliendo pueden disparar alarmas -esto ya lo hace System Center Operations Manager, no la herramienta de modelado, claro)
-Serie sobre Diseño para Operaciones
http://channel9.msdn.com/shows/The_DFO_Show
Es un grupo de presentaciones de unos 7 minutos cada una aprox, donde el presentador da recomendaciones acerca de cómo hacer aplicaciones que luego habiliten parámetros medibles durante la ejecución
-Architectural Issues in Managing Web Services in Connected Systems
http://msdn2.microsoft.com/en-us/architecture/ms954616.aspx
Paper sobre consideraciones de arquitectura al diseñar servicios web que sean "administrables". Enmarcado en modelado de salud, no hace incapié específico en ASP.NET sino que es más agnóstico
-Web Service Health Modeling, Instrumentation, and Monitoring
http://msdn2.microsoft.com/en-us/architecture/ms954618.aspx
Ciclo completo de modelado de salud, instrumentación (durante el desarrollo) y monitoreo (durante la ejecución) de nuestros servicios web. De nuevo es agnóstico. Ahora vienen los ASP.NET específicos
-ASP.NET Health Monitoringhttp://msdn2.microsoft.com/en-us/architecture/ms178701.aspx
Este link es un catálogo a diversas API\’s tanto de .NET en general como específicas de ASP.NET para poner en práctica el monitoreo de la salud de nuestra aplicación. Muy en la línea de lo que contaste vos, Jotapé
-How To: Use Health Monitoring in ASP.NET 2.0
http://msdn2.microsoft.com/en-us/architecture/ms998306.aspx
Esto lo hizo la gente de Patterns and Practices y va más enfocado al cómo que al qué del monitoreo de salud en ASP.NET (el qué estaba dado en los links anteriores)
-MSDN Webcast: Instrumentation, Logging, and Error Handling in ASP.NET Applications
Complementario a lo anterior, un webcast más para desarrolladores que para arquitectos, donde se muestra la piedra angular de la instrumentación en .NET y en la plataforma Windows en general: WMI
Un abrazo y congrats por el post!!
Hola Dagum,
Gracias por tu comentario, en rigor es mucho más amplio que el post
Jajajajaja!!!!!
Nos Vemos pronto en Redmond si todo sale bien 😉
Estimado
Me fascinó la manera en que escribe sobre el tema.
Seguiré regresando esta web para continuar aprendiendo sobre el rubro.
Saludos
Excelente port, felicidades