Autor: Rob Howard Traducción: Peces tropicales
Este artículo analiza:
· Secretos generales de rendimiento de ASP.NET
· Consejos y trucos útiles para mejorar el rendimiento de ASP.NET
· Recomendaciones para usar bases de datos en ASP.NET
· Almacenamiento en caché y procesamiento en segundo plano en ASP.NET
Escribir una aplicación web utilizando ASP.NET es increíblemente sencillo. Es tan simple que muchos desarrolladores no se toman el tiempo para crear sus aplicaciones para que funcionen bien. En este artículo, recomiendo 10 consejos para escribir aplicaciones web de alto rendimiento. No limitaré mi discusión a las aplicaciones ASP.NET, porque las aplicaciones ASP.NET son sólo un subconjunto de las aplicaciones web. Este artículo no pretende ser una guía definitiva para optimizar el rendimiento de las aplicaciones web; un libro completo podría lograrlo fácilmente. Más bien, deberíamos considerar este artículo como un buen punto de partida.
Antes de convertirme en adicto al trabajo, practicaba mucho la escalada. Antes de hacer cualquier escalada prefiero mirar las rutas en alguna guía de viajes y leer recomendaciones de personas que han estado en la cumbre. Pero no importa qué tan bien escrita esté una guía, necesitas experiencia real en escalada antes de intentar un objetivo desafiante. De manera similar, sólo puedes aprender a escribir aplicaciones web de alto rendimiento cuando te enfrentas a solucionar problemas de rendimiento o ejecutar un sitio de alto rendimiento.
Mi experiencia personal proviene de trabajar como Foundation Program Manager en el equipo ASP.NET de Microsoft, mantener y administrar www.asp.net y ayudar a diseñar Community Server, una de varias aplicaciones ASP.NET conocidas (foros ASP.NET). , .Text y nGallery conectados a una plataforma). Seguro que algunos de estos consejos que a mí me han ayudado te serán útiles a ti también.
Debería considerar separar su aplicación en varias capas lógicas. Es posible que haya oído hablar de la arquitectura de 3 niveles (o n niveles). Generalmente se trata de patrones estructurales prescritos que dividen físicamente el negocio y/o el hardware en divisiones funcionales. Si el sistema requiere una escala mayor, se puede agregar fácilmente más hardware. Sin embargo, eso producirá una degradación del rendimiento asociada con los saltos empresariales y de máquinas, por lo que debemos evitarlo. Por lo tanto, siempre que sea posible, intente ejecutar la página ASP.NET y los componentes relacionados de la página en la misma aplicación.
Debido a la separación del código y los límites entre capas, el uso de servicios web o la comunicación remota puede reducir el rendimiento en un 20 % o más.
La capa de datos es un poco diferente porque normalmente es mejor tener hardware dedicado a la base de datos. Sin embargo, el costo del proceso que salta a la base de datos sigue siendo alto, por lo que el rendimiento en la capa de datos debe ser su primera consideración al optimizar su código.
Antes de invertir en solucionar los problemas de rendimiento de su aplicación, asegúrese de analizarla para descubrir la causa raíz del problema. Los contadores clave de rendimiento (como el que indica el porcentaje de tiempo dedicado a realizar la recolección de basura) también son muy útiles para descubrir dónde pasa la aplicación la mayor parte de su tiempo. Aunque aquellos lugares donde se pasa el tiempo suelen ser menos intuitivos.
En este artículo analizo dos formas de mejorar el rendimiento: optimizaciones a gran escala, como el uso del almacenamiento en caché de ASP.NET, y optimizaciones a pequeña escala, que se repiten con frecuencia. Estas pequeñas piezas de optimización son a veces las más interesantes. Un pequeño cambio que realice en su código se llamará miles de veces. Optimice grandes porciones y podrá encontrar un gran salto en el rendimiento general. Al optimizar en pequeñas partes, puede reducir algunos microsegundos de una solicitud determinada, pero de forma acumulativa en todas las solicitudes por día, obtendrá una mejora inesperada en el rendimiento.
Rendimiento en la capa de datos
Cuando comienzas a optimizar el rendimiento de una aplicación, hay una prueba decisiva que puedes priorizar: ¿Necesita el código acceder a una base de datos? Si es así, ¿con qué frecuencia lo visitas? Tenga en cuenta que esta prueba también se puede aplicar al código que utiliza servicios web o control remoto, pero no los cubriré en este artículo.
Si se requiere una solicitud de base de datos en una determinada ruta de código de su código y encuentra otros lugares donde desea priorizar las optimizaciones, como la manipulación de cadenas, deténgase y realice las pruebas críticas primero. A menos que tenga que lidiar con un problema de rendimiento realmente grave, será mejor invertir su tiempo en optimizar el tiempo que lleva conectarse a la base de datos, la cantidad de datos devueltos y las operaciones que realiza hacia y desde la base de datos.
Ahora que he cubierto la información en general, veamos 10 consejos para ayudar a que su aplicación funcione mejor. Comenzaré con aquellos que tienen el impacto más obvio en la mejora del rendimiento.
Consejo 1: devolver varios conjuntos de resultados
Eche un vistazo al código de su base de datos para ver si tiene rutas de solicitud que accedan a la base de datos más de una vez. Cada uno de estos viajes de ida y vuelta reduce la cantidad de solicitudes que su aplicación puede atender por segundo. Al devolver varios conjuntos de resultados en una única solicitud de base de datos, puede reducir el tiempo total consumido por la comunicación de la base de datos. Después de reducir la cantidad de solicitudes que su servidor de base de datos debe administrar, también hace que su sistema sea más escalable.
Generalmente puede usar declaraciones SQL dinámicas para devolver múltiples conjuntos de resultados; yo prefiero usar procedimientos almacenados. Es discutible si se debe poner la lógica de negocios en un procedimiento almacenado, pero creo que si la lógica en un procedimiento almacenado puede limitar los datos devueltos (reduce el tamaño del conjunto de datos, el tiempo dedicado a la conexión de red y elimina la necesidad de filtrar datos de la capa lógica), entonces es algo bueno.
Al utilizar una instancia de SqlCommand y su método ExecuteReader para generar una clase empresarial fuertemente tipada, puede mover el puntero del conjunto de resultados hacia adelante llamando a NextResult. La Figura 1 muestra una sesión de ejemplo que utiliza una clase definida para generar varias ArrayLists. Devolver solo los datos que necesita de la base de datos reducirá significativamente las solicitudes de memoria en su servidor.
1// leer el primer conjunto de resultados
2lector = comando.ExecuteReader();
3
4// leer los datos de ese conjunto de resultados
5mientras (lector.Leer()) {
6 proveedores.Add(PopulateSupplierFromIDataReader(lector));
7}
8
9// leer el siguiente conjunto de resultados
10lector.SiguienteResultado();
11
12// leer los datos de ese segundo conjunto de resultados
13mientras (lector.Leer()) {
14 productos.Add(PopulateProductFromIDataReader(lector));
15}
16
17
Consejo 2: acceso a datos paginados
DataGrid de ASP.NET proporciona una gran capacidad: soporte para paginación de datos. Cuando se configura la paginación en DataGrid, se mostrará una cantidad específica de resultados a la vez. Además, en la parte inferior del DataGrid se muestra una interfaz de usuario de paginación para navegar entre los resultados. La interfaz de usuario paginada le permite navegar hacia adelante o hacia atrás a través de los datos mostrados, mostrando una cantidad específica de resultados por página.
Pero hay un pequeño problema. Cuando se utiliza DataGrid para paginación, todos los datos deben estar vinculados a la tabla. Por ejemplo, su capa de datos deberá devolver todos los datos y luego DataGrid deberá completar todos los registros que se mostrarán en función de la página actual. Si se devuelven 100.000 registros cuando utiliza la paginación DataGrid, se descartarán 99.975 registros por solicitud (suponiendo que la capacidad de cada página sea de 25 registros). Cuando el número de registros crece, el rendimiento de la aplicación se ve muy afectado porque se deben devolver más y más datos con cada solicitud.
Una forma de escribir un mejor código de paginación es utilizar procedimientos almacenados. La Figura 2 muestra un procedimiento almacenado de muestra que pagina la tabla de datos de Órdenes en la base de datos de Nothwind. Básicamente, todo lo que necesitas hacer aquí es pasar el índice de la página y la capacidad de la página. La base de datos calcula los conjuntos de resultados apropiados y los devuelve.
1CREAR PROCEDIMIENTO northwind_OrdersPagged
2(
3 @PageIndex entero,
4 @PageSizeint
5)
6AS
7COMENZAR
8DECLARAR @PageLowerBound int
9DECLARAR @PageUpperBound int
10DECLARAR @RowsToReturn int
11
12-- Primero configure el recuento de filas
13SET @RowsToReturn = @PageSize * (@PageIndex + 1)
14SET ROWCOUNT @RowsToReturn
15
16--Establecer los límites de la página
17SET @PageLowerBound = @PageSize * @PageIndex
18SET @PageUpperBound = @PageLowerBound + @PageSize + 1
19
20-- Crea una tabla temporal para almacenar los resultados seleccionados
21CREAR TABLA #PageIndex
Veintidós(
23 IndexId int IDENTIDAD (1, 1) NO NULO,
24 ID de pedido int
25)
26
27--Insertar en la tabla temporal
28INSERTAR EN #PageIndex (ID de pedido)
29SELECCIONAR
30 ID de pedido
31DESDE
32 pedidos
33ORDENAR POR
34 ID de pedido DESC
35
36--Recuento total de retorno
37SELECCIONE RECUENTO (ID de pedido) DE Órdenes
38
39-- Devolver resultados paginados
40SELECCIONAR
41 O.*
42DESDE
43 Órdenes Oh,
44 #PageIndex Índice de páginas
45DONDE
46 O.IDPedido = PageIndex.IDPedido Y
47 PageIndex.IndexID > @PageLowerBound Y
48 PageIndex.IndexID < @PageUpperBound
49ORDENAR POR
50 Índice de página.ID de índice
51
52FIN
53
54
Durante el período de servicio comunitario, escribimos un control de servidor de paginación para realizar esta paginación de datos. Notarás que utilicé la idea analizada en el Consejo 1 para devolver dos conjuntos de resultados de un procedimiento almacenado: el número total de registros y los datos solicitados.
El número total de registros devueltos puede variar según la solicitud realizada. Por ejemplo, se puede utilizar una cláusula WHERE para restringir los datos devueltos. Debemos conocer la cantidad total de registros que se devolverán para poder calcular la cantidad total de páginas que se mostrarán en la interfaz de usuario paginada. Por ejemplo, si hay 1.000.000 de registros en total y se utiliza una cláusula WHERE para filtrar esos registros a 1.000 registros, la lógica de paginación necesita conocer el número total de registros para enviar la interfaz de usuario de paginación de forma adecuada.
Consejo 3: agrupación de conexiones
Establecer una conexión TCP entre su aplicación web y SQL Server puede ser una operación costosa. Los desarrolladores de Microsoft han estado utilizando la agrupación de conexiones durante algún tiempo, lo que les permite reutilizar conexiones a bases de datos. En lugar de establecer una nueva conexión TCP para cada solicitud, se establece una nueva conexión sólo cuando no hay ninguna conexión disponible en el grupo de conexiones. Cuando se cierra la conexión, se devuelve al grupo de conexiones; aún mantiene la conexión a la base de datos, en lugar de destruir completamente la conexión TCP.
Por supuesto, hay que tener cuidado con las conexiones con fugas. Cierre siempre sus conexiones cuando haya terminado de usarlas. Repito: no importa lo que digan sobre el mecanismo de recolección de basura de Microsoft .NET Framework, siempre debes llamar explícitamente al método Close o Dispose en tu conexión cuando hayas terminado. No confíe en Common Language Runtime (CLR) para limpiar y cerrar su conexión en un momento predeterminado. El CLR eventualmente destruirá la clase y forzará el cierre de la conexión, pero no tiene garantía de cuándo se ejecutará realmente el mecanismo de recolección de basura en el objeto.
Para lograr los mejores resultados al utilizar la agrupación de conexiones, debe seguir algunas reglas. Primero, abra una conexión, haga el trabajo y luego cierre la conexión. Está bien si tiene que (preferiblemente aplicando el consejo 1) abrir y cerrar la conexión varias veces por solicitud, es mucho mejor que dejar la conexión abierta y pasarla a varios métodos diferentes. En segundo lugar, utilice la misma cadena de conexión (y, por supuesto, el mismo ID de hilo si utiliza la autenticación integrada). Si no utiliza la misma cadena de conexión, por ejemplo diferentes cadenas de conexión personalizadas según el usuario que inició sesión, no obtendrá el mismo valor óptimo que proporciona el grupo de conexiones. Y si utiliza la autenticación integrada cuando se hace pasar por una gran cantidad de usuarios, su grupo de conexiones también será mucho menos eficiente. Los contadores de rendimiento de datos .NET CLR pueden resultar útiles al intentar localizar cualquier problema de rendimiento relacionado con la agrupación de conexiones.
Siempre que su aplicación se conecte a un recurso, como una base de datos, o se ejecute en otro proceso, debe hacerlo centrándose en el tiempo que lleva conectarse al recurso, el tiempo que lleva enviar y recibir datos y el tiempo que tarda en conectarse. se tarda en enviar y recibir datos. Hay una serie de viajes de ida y vuelta a la base de datos para optimizar. Optimizar cualquier tipo de salto de proceso en su aplicación es el primer paso para comenzar a lograr un mejor rendimiento.
La capa de aplicación contiene la lógica que se conecta a su capa de datos y transforma los datos en instancias de clase y procesos lógicos significativos. Por ejemplo, en un servidor comunitario, aquí es donde se genera un foro o una colección de hilos y se aplican reglas comerciales como permisos; lo que es más importante, aquí es donde se realiza la lógica de almacenamiento en caché;
Consejo 4: API de almacenamiento en búfer de ASP.NET
Lo primero que debe considerar antes de comenzar a escribir la primera línea de código en su aplicación es diseñar la capa de aplicación para maximizar y aprovechar las funciones de almacenamiento en caché de ASP.NET.
Si su componente se ejecuta dentro de una aplicación ASP.NET, simplemente haga referencia a System.Web.dll en su proyecto de aplicación. Cuando necesite acceder al caché, use la propiedad HttpRuntime.Cache (también se puede acceder a este objeto a través de Page.Cache y HttpContext.Cache).
Existen varias pautas para utilizar datos almacenados en caché. En primer lugar, si los datos se pueden utilizar varias veces, almacenarlos en caché es una buena opción. En segundo lugar, si los datos son generales y no específicos de una solicitud o usuario específico, almacenarlos en caché es una excelente opción. Si los datos son específicos de un usuario o de una solicitud, pero tienen una vida útil prolongada, se pueden almacenar en caché, pero no se pueden usar con frecuencia. En tercer lugar, un principio que a menudo se pasa por alto es que a veces se puede almacenar en caché demasiado. Normalmente, en una máquina x86, para reducir la probabilidad de errores de falta de memoria, querrás ejecutar un proceso que no utilice más de 800 MB de bytes privados. Por lo tanto, el almacenamiento en caché debe ser limitado. En otras palabras, es posible que necesite reutilizar el resultado de un cálculo, pero si ese cálculo requiere diez parámetros, es posible que deba intentar almacenar en caché 10 permutaciones, y eso podría causarle problemas. Los errores de falta de memoria debido al exceso de caché son los más comunes en ASP.NET, especialmente con grandes conjuntos de datos.
El almacenamiento en caché tiene varias características excelentes que debes conocer. Primero, el caché implementa un algoritmo usado menos recientemente, lo que permite a ASP.NET forzar el vaciado del caché (eliminando automáticamente los elementos no utilizados del caché) cuando la memoria se ejecuta de manera menos eficiente. En segundo lugar, la caché admite dependencias caducadas que se pueden forzar a caducar. Estas dependencias incluyen tiempo, claves y archivos. A menudo se utiliza el tiempo, pero con ASP.NET 2.0, se introduce un tipo de invalidación nuevo y más potente: la invalidación de la caché de la base de datos. Se refiere a eliminar automáticamente elementos en el caché cuando cambian los datos en la base de datos. Para obtener más información sobre la invalidación de la caché de bases de datos, consulte la columna Dino Esposito Cutting Edge en la edición de julio de 2004 de MSDN Magazine. Para comprender la arquitectura del caché, consulte la Figura 3.
Consejo 5: almacenamiento en caché por solicitud
Anteriormente en este artículo, mencioné que pequeñas mejoras en las rutas de código que se recorren con frecuencia pueden generar grandes ganancias de rendimiento general. De estas pequeñas mejoras, una es definitivamente mi favorita y la llamo almacenamiento en caché por solicitud.
Las API de almacenamiento en caché están diseñadas para almacenar datos en caché durante un período de tiempo más largo o hasta que se cumplan ciertas condiciones, pero el almacenamiento en caché por solicitud significa almacenar datos en caché solo durante la duración de esa solicitud. Para cada solicitud, se accede con frecuencia a una ruta de código específica, pero los datos se extraen, aplican, modifican o actualizan solo una vez. Esto suena un poco teórico, así que demos un ejemplo concreto.
En una aplicación de foro de servidor comunitario, cada control de servidor utilizado en la página requiere datos de personalización para determinar qué apariencia usar, qué tabla de estilos usar y otros datos de personalización. Algunos de estos datos se pueden almacenar en caché a largo plazo, pero algunos datos se recuperan solo una vez por solicitud y luego se reutilizan varias veces durante esa solicitud, como por ejemplo para la apariencia de un control.
Para lograr el almacenamiento en caché por solicitud, utilice ASP.NET HttpContext. Para cada solicitud, se crea una instancia de HttpContext y se puede acceder a ella desde cualquier lugar dentro de la propiedad HttpContext.Current durante la solicitud. La clase HttpContext tiene una propiedad de colección de Elementos especial, los objetos y los datos agregados a esta colección de Elementos se almacenan en caché solo mientras dure la solicitud. Así como puede usar el almacenamiento en caché para almacenar datos a los que se accede con frecuencia, también puede usar HttpContext.Items para almacenar datos que solo se usan por solicitud. La lógica detrás de esto es muy simple: los datos se agregan a la colección HttpContext.Items cuando no existe, y en búsquedas posteriores, solo se devuelven los datos en HttpContext.Items.
Consejo 6: procesamiento en segundo plano
El camino hacia el código debería ser lo más rápido posible, ¿verdad? Puede haber ocasiones en las que descubra que está realizando una tarea que requiere muchos recursos y que se realiza en cada solicitud o cada n solicitudes. Enviar correos electrónicos o analizar y validar datos entrantes son algunos ejemplos.
Al analizar ASP.NET Forums 1.0 y rediseñar el contenido que conforma el servidor comunitario, descubrimos que la ruta del código para publicar nuevas publicaciones era extremadamente lenta. Cada vez que se publica una nueva publicación, la aplicación primero debe asegurarse de que no haya publicaciones duplicadas, luego debe analizar la publicación usando un filtro de "malas palabras", analizar los emoticonos de los caracteres de la publicación, etiquetar e indexar la publicación y agregar el publicar en la solicitud cuando se solicite, agregarlo a la cola correspondiente, validar el archivo adjunto y, finalmente, enviar una notificación por correo electrónico a todos los suscriptores inmediatamente después de que se publique la publicación. Claramente, hay mucho involucrado.
Después de la investigación, se descubrió que la mayor parte del tiempo se dedicaba a indexar la lógica y enviar correos electrónicos. Indexar publicaciones es una operación que requiere mucho tiempo y se descubrió que la funcionalidad integrada System.Web.Mail se conecta a un servidor SMTP y luego envía correos electrónicos continuamente. A medida que aumenta el número de suscriptores de una publicación o área temática en particular, la función AddPost tarda cada vez más en ejecutarse.
No se requiere la indexación de correo electrónico para todas las solicitudes. Idealmente, nos gustaría realizar esta operación por lotes, indexando 25 publicaciones a la vez o enviando todos los correos electrónicos cada cinco minutos. Decidimos usar el código que había usado para crear un prototipo de invalidación de caché de datos que finalmente se incluyó en Visual Studio 2005.
La clase Timer en el espacio de nombres System.Threading es muy útil, pero no muy conocida en .NET Framework, al menos entre los desarrolladores web. Una vez creada, esta clase Timer llamará a la devolución de llamada especificada en un intervalo configurable para un subproceso en ThreadPool. Esto significa que puede configurar su código para que se ejecute sin solicitudes entrantes a la aplicación ASP.NET, lo cual es ideal para el procesamiento en segundo plano. También puede realizar operaciones como indexar o enviar correos electrónicos en este proceso en segundo plano.
Sin embargo, existen varios problemas con esta tecnología. Si se desinstala el dominio de la aplicación, esta instancia del temporizador dejará de activar eventos. Además, debido a que CLR tiene un estándar estricto para la cantidad de subprocesos por proceso, puede haber una situación en un servidor muy cargado donde el temporizador no garantice que los subprocesos continúen completando la operación y, hasta cierto punto, puede causar retrasos. . ASP.NET intenta minimizar la posibilidad de que esto suceda manteniendo una cierta cantidad de subprocesos disponibles en el proceso y utilizando solo una parte del total de subprocesos para el procesamiento de solicitudes. Sin embargo, esto puede ser un problema si tiene muchas operaciones asincrónicas.
No hay suficiente espacio aquí para este código, pero puede descargar un ejemplo fácil de entender en www.rob-howard.net . Vea las diapositivas y demostraciones de la presentación Blackbelt TechEd 2004.
Consejo 7: almacenamiento en caché de resultados de página y servidores proxy
ASP.NET es su capa de presentación (o debería ser su capa de presentación); consta de páginas, controles de usuario, controles de servidor (HttpHandlers y HttpModules) y el contenido que generan. Si tiene una página ASP.NET que genera resultados (HTML, XML, imágenes o cualquier otro dato) y cuando ejecuta este código en cada solicitud, genera el mismo resultado, entonces tiene una herramienta que puede usarse para A. Gran alternativa al almacenamiento en caché de resultados de páginas.
Agregando la siguiente línea en la parte superior de la página:
<%@ Página OutputCache VaryByParams="none" Duration="60" %>
Puede generar efectivamente resultados para esta página una vez y luego reutilizarlos varias veces durante hasta 60 segundos, momento en el cual la página se volverá a ejecutar y el resultado se agregará nuevamente al caché de ASP.NET. Este comportamiento también se puede lograr utilizando algunas API programables de bajo nivel. Hay varias opciones configurables para el almacenamiento en caché de resultados, como la propiedad VaryByParams que acabamos de mencionar. VaryByParams solo se solicita, pero también le permite especificar parámetros HTTP GET o HTTP POST para cambiar las entradas de la caché. Por ejemplo, simplemente configure VaryByParam="Report" para almacenar en caché la salida para default.aspx?Report=1 o default.aspx?Report=2. Se pueden especificar parámetros adicionales especificando una lista separada por punto y coma.
Mucha gente no se da cuenta de que cuando se utiliza el almacenamiento en caché de resultados, las páginas ASP.NET también generan encabezados HTTP que fluyen hacia los servidores de almacenamiento en caché, como los utilizados por Microsoft Internet Security and Acceleration Server o Akamai. Después de configurar el encabezado de la tabla de caché HTTP, los documentos se pueden almacenar en caché en estos recursos de red y las solicitudes de los clientes se pueden satisfacer sin regresar al servidor de origen.
Por lo tanto, el uso del almacenamiento en caché de salida de página no hará que su aplicación sea más eficiente, pero puede reducir la carga en el servidor porque la tecnología de almacenamiento en caché descendente almacena en caché el documento. Por supuesto, esto solo puede ser contenido anónimo; una vez que se descarga, nunca volverá a ver las solicitudes y ya no podrá realizar la autenticación para evitar el acceso a ellas.
Consejo 8: ejecute IIS 6.0 (incluso solo para usar la caché del kernel)
Si no está ejecutando IIS 6.0 (Windows Server 2003), se está perdiendo algunas grandes mejoras de rendimiento en los servidores web de Microsoft. En el consejo 7, hablé del almacenamiento en caché de resultados. En IIS 5.0, las solicitudes pasan por IIS y luego por ASP.NET. Cuando se trata de almacenamiento en caché, HttpModule en ASP.NET recibe la solicitud y devuelve el contenido del caché.
Si está utilizando IIS 6.0, encontrará una pequeña característica llamada caché del kernel que no requiere ningún cambio de código en ASP.NET. Cuando ASP.NET realiza una solicitud de almacenamiento en caché de resultados, el caché del kernel de IIS recibe una copia de los datos almacenados en caché. Cuando una solicitud proviene de un controlador de red, el controlador a nivel de kernel (sin cambio de contexto al modo de usuario) recibe la solicitud, vacía los datos almacenados en caché en la respuesta, si está en caché, y luego completa la ejecución. Esto significa que cuando utilice el almacenamiento en caché en modo kernel con el almacenamiento en caché de salida de IIS y ASP.NET, verá resultados de rendimiento increíbles. Durante el desarrollo de ASP.NET en Visual Studio 2005, fui el gerente de desarrollo responsable del rendimiento de ASP.NET. Los desarrolladores hacen el trabajo específico, pero yo puedo ver todos los informes que se generan todos los días. Los resultados de la caché en modo kernel son siempre los más interesantes. La característica más común es que la red está inundada de solicitudes/respuestas, mientras que IIS se ejecuta con solo un 5 % de uso de CPU. ¡Esto es impactante! Por supuesto, existen otras razones para utilizar IIS 6.0, pero el almacenamiento en caché en modo kernel es la más obvia.
Consejo 9: utilice la compresión Gzip
Aunque usar gzip no es necesariamente un truco para el rendimiento del servidor (ya que puede ver un aumento en el uso de la CPU), el uso de la compresión gzip puede reducir la cantidad de bytes enviados por el servidor. Esto da como resultado un aumento percibido en la velocidad de la página y un uso reducido del ancho de banda. Dependiendo de los datos que se envían, qué tan comprimibles pueden ser y si el navegador del cliente los admite (IIS solo enviará contenido comprimido con gzip a clientes que admitan la compresión gzip, como Internet Explorer 6.0 y Firefox), su servidor puede servir Más solicitudes. De hecho, casi cada vez que reduce la cantidad de datos devueltos, aumenta la cantidad de solicitudes por segundo.
La compresión gzip está integrada en IIS 6.0 y su rendimiento es mucho mejor que la compresión gzip utilizada en IIS 5.0, lo cual es una buena noticia. Desafortunadamente, al intentar activar la compresión gzip en IIS 6.0, es posible que no pueda encontrar la configuración en el cuadro de diálogo Propiedades de IIS. El equipo de IIS incorporó una excelente funcionalidad gzip al servidor, pero olvidó incluir una interfaz de usuario administrativa para habilitarla. Para habilitar la compresión gzip, debe profundizar en los ajustes de configuración XML de IIS 6.0 (para que no se debilite). Por cierto, el crédito es para Scott Forsyth de OrcsWeb por ayudarme a plantear este problema con el servidor www.asp.net alojado en OrcsWeb.
Este artículo no describirá los pasos. Lea el artículo de Brad Wilson en Compresión IIS6. También hay un artículo de la base de conocimientos sobre cómo habilitar la compresión para ASPX en Habilitar compresión ASPX en IIS. Sin embargo, debe tener en cuenta que, debido a algunos detalles de implementación, la compresión dinámica y el almacenamiento en caché del kernel no pueden existir simultáneamente en IIS 6.0.
Consejo 10: Estado de la vista de control del servidor
Ver estado es un nombre interesante para ASP.NET que almacena algunos datos de estado en campos de salida ocultos de la página generada. Cuando la página se devuelve al servidor, el servidor puede analizar, validar y aplicar estos datos de estado de vista al árbol de control de la página. Ver estado es una característica muy poderosa porque permite que el estado persista en el cliente y no requiere cookies ni memoria del servidor para guardar este estado. Muchos controles de servidor ASP.NET utilizan el estado de vista para conservar la configuración creada durante las interacciones con elementos de la página, como guardar la página actual que se muestra al paginar datos.
Sin embargo, utilizar el estado de vista también tiene algunas desventajas. En primer lugar, aumenta la carga general de la página cuando se publica o solicita. También se produce una sobrecarga adicional al serializar o deserializar los datos del estado de la vista enviados de vuelta al servidor. Finalmente, el estado de vista aumenta la asignación de memoria en el servidor.
Varios controles de servidor tienden a abusar del estado de vista incluso cuando no es necesario, el más notable de los cuales es DataGrid. El comportamiento predeterminado de la propiedad ViewState está activado, pero puede desactivarlo en el nivel de control o de página si no lo necesita. Dentro del control, simplemente establezca la propiedad EnableViewState en falso o configúrela globalmente en la página usando la siguiente configuración:
<%@ Página EnableViewState="false" %>
Si no vuelve a publicar la página o siempre regenera los controles de la página en cada solicitud, debe desactivar el estado de visualización a nivel de página.
resumen
Le he dado algunos consejos que encuentro útiles al escribir aplicaciones ASP.NET de alto rendimiento. Como mencioné anteriormente en este artículo, esta es una guía preliminar y no la última palabra sobre el rendimiento de ASP.NET. (Para obtener información sobre cómo mejorar el rendimiento de la aplicación ASP.NET, consulte Mejora del rendimiento de ASP.NET). La mejor manera de resolver un problema de rendimiento específico solo puede encontrarse a través de su propia experiencia. Sin embargo, estos consejos deberían brindarle una buena orientación en su viaje. En el desarrollo de software, existen pocos absolutos; cada aplicación es única.
Consulte la barra lateral "Mitos comunes sobre el rendimiento".
Rob Howard es el fundador de Telligent Systems, que se especializa en aplicaciones web de alto rendimiento, gestión de bases de conocimientos y sistemas de colaboración. Rob trabajó anteriormente en Microsoft, donde ayudó a diseñar la infraestructura para ASP.NET 1.0, 1.1 y 2.0. Para ponerse en contacto con Rob, visite [email protected] .
Enlace original: http://msdn.microsoft.com/msdnmag/issues/05/01/ASPNETPerformance/default.aspx