Gestión de concurrencia en IIS 6

El proceso fundamental de creación de hilos (threads) se describe a continuación:

En primer lugar se reserva memoria para un objeto de núcleo. Se inicializa éste y se reserva memoria en la pila para el propio hilo y se inicializa. El sistema envía a cada DLL en el proceso una notificación DLL_THREAD_ATTACH y se paginan en memoria los contenidos necesarios del disco de forma que el código pueda ejecutarse. Cuando un hilo muere, se envía una notificación DLL_THREAD_DETACH, se libera la memoria reservada en la pila para el hilo y se libera el objeto del núcleo cuando su cuenta de uso se haga cero.

A partir de la introducción del ThreadPool en el CLR (decisión tomada por Microsoft en su momento orientada fundamentalmente a proporcionar funcionalidades de threading para sistemas anteriores a Windows 2000 y a optimizar la sobrecarga de recursos que implica la gestión de hilos), cuando se inicializa, el pool no contiene hilo alguno hasta el momento en que una aplicación necesita crearlo para realizar una tarea t. Dicha tarea debe solicitar específicamente su ejecución en un hilo del pool. En ese momento el pool crea un hilo inicial h1 (del mismo modo que el descrito en el párrafo anterior), pero con un importante matiz: cuando la tarea se completa, el hilo h1 no se destruye, sino que se retorna al pool en un estado de suspensión. Cuando la aplicación realiza otra petición al pool, se activa el hilo suspendido h1 que ejecuta la nueva tarea, mecanismo que optimiza la gestión de hilos al eliminar la sobrecarga efectiva que supone la creación y destrucción de los mismos.

Así pues, supongamos que la aplicación A1 necesita ejecutar un conjunto de n tareas {t1, t2, t3, …, tn}. Para la ejecución de t1 el pool crea el hilo h1. Si el tiempo de encolado de tareas por parte de la aplicación no supera el tiempo de ejecución de cada una de ellas más cuarenta segundos, el pool reutiliza el hilo h1 optimizando el rendimiento del sistema. Los cuarenta segundos adicionales son el tiempo máximo de inactividad de un hilo, periodo después del cual el hilo se activa y se destruye liberando todos los recursos retenidos, si bien es necesario tener en cuenta que este valor no está documentado y puede variar.

En caso de que las n tareas a ejecutar se encolen a mayor velocidad, se crearán múltiples hilos en los que se ejecutarán las tareas que la aplicación encole en el pool del CLR.

ASP .NET procesa las llamadas obviamente mediante el ThreadPool: cuando una aplicación ASP .NET alojada en IIS 6.0 recibe una petición, esta se entrega a ASP .NET en un hilo de entrada / salida. ASP .NET la envía inmediatamente al pool que devuelve una notificación HSE_STATUS_PENDING a IIS. Esto libera hilos en IIS a fin de optimizar recursos. Asimismo, y como ya hemos comentado, el pool ajusta automáticamente el número de hilos conforme a la carga, de modo que si el rendimiento de las peticiones es alto se crearán uno o dos hilos por CPU y si es malo (elevada latencia) habrá un número de hilos mayor (un detalle a tener en cuenta es que hasta que un hilo se activa, la memoria reservada por este es nativa, sólo cuando recibe la petición y comienza su ejecución se reserva memoria gestionada).

ASP .NET impone una restricción sobre número de hilos concurrentes ejecutando peticiones limitándolos en número para evitar un consumo excesivo de recursos. Esta limitación se controla en versiones previas a 2.0 con las configuraciones httpRuntime/minFreeThreads y httpRuntime/minLocalRequestFreeThreads (machine.config), sin embargo en 2.0 y versiones posteriores se ha simplificado esta configuración introduciendo processModel/autoConfig que por defecto limita a 12 el número máximo de hilos concurrentes para ejecución de peticiones por cada CPU.

El modo más adecuado de analizar un servidor a fin de detectar posibles problemas de rendimiento en solicitudes de servicios Web desde aplicaciones ASP.NET, es monitorizar el contador de rendimiento “ASP.NET Applications\Requests in Application Queue”: si el valor de dicho contador es superior a cero, podemos determinar que existe un problema de rendimiento.

Comentarios

Entradas populares