martes, 19 de junio de 2012

Reciclaje de grupos de aplicaciones en IIS

Lo cierto es que, aunque conocía la característica de reciclaje de un grupo de aplicaciones de IIS, hasta hoy no había tenido la necesidad de meterme con ella en serio.

Normalmente, cuando subo una aplicación a IIS los únicos parámetros que configuro del grupo de aplicaciones es seleccionar la versión del .NET Framework correcta. En la mayoría de los casos no hay mucho más que hacer al respecto pero, como te mostraré a continuación, en según qué escenarios podría no ser suficiente.

Imagina una aplicación que realiza ciertas tareas pesadas o críticas (lo dejo a tu elección) al arranque de la aplicación (por ejemplo en el evento Application_OnStart del fichero global.asax).

Con este escenario ¿Sabes con certeza en que momentos será ejecutado tu código de inicialización? Está claro que se ejecutará al levantar el grupo de aplicaciones asociado a tu aplicación pero ¿Cuándo y porqué se vuelve a levantar tu grupo de aplicaciones?

Las respuestas más obvias es que un grupo de aplicaciones se iniciará en los siguientes casos:

  • Reinicio del servicio W3C
    • Bien sea de forma manual, bien porque se ha reiniciado el servidor, etc.
  • Reinicio o reciclaje manual del grupo de aplicaciones.
    • Acto totalmente voluntario y, por ende, controlable.
  • Cambios en la configuración de la aplicación (web.config, global.asax, etc.).
    • De nuevo un acto voluntario y programable.

A partir de aquí es cuando me he encontrado que, muy diversos factores también podrían forzar el reciclaje del grupo de aplicaciones y, por consiguiente, que mi código pesado de inicialización volviera a ejecutarse cuando yo no lo tenía previsto.

Si accedemos a la “configuración avanzada” de un grupo de aplicaciones desde la consola de administración de IIS, las secciones que podrían interesarnos son: Modelo de proceso y Reciclaje.

clip_image001[4]

Sin meternos en configurar límites de memoria o CPU, que al ser alcanzados provocarían el reciclaje de la aplicación, hay otros valores que “de serie” pueden hacer que nuestro grupo de aplicaciones se recicle sin nosotros haberlo previsto. Principalmente estoy hablando de “Tiempo de inactividad” e “Intervalo de tiempo regular”.

Tiempo de inactividad” ha sido el mayor de mis problemas durante algún tiempo y, de hecho, es el valor que ha originado la redacción de este post. Este valor indica un cantidad de minutos en las que, sino hay actividad en el servidor, el grupo de aplicaciones será reiniciado.

En IIS 7.5 tiene por defecto el valor 5, lo que significa que si en 5 minutos nadie hace una petición a tu aplicación… el grupo de aplicaciones se reciclará.

Por otro lado, “Intervalo de tiempo regular” es un valor, también expresado en minutos, después de los cuales se reciclará el grupo de aplicaciones, con independencia de si están o activas las aplicaciones del grupo.

Por defecto son 1740 minutos (29 horas).

En esta situación resulta que tengo una aplicación que se recicla después de 5 minutos de inactividad y además cada 29 horas… luego se recicla cuando quiere y no tengo nada controlado el tema!

Para solucionar esto he optado por utilizar el valor “Horas específicas”, que permite especificar una o más horas en las cuales será reciclado el grupo de aplicaciones. En mi caso he pasado de un “reciclado aleatorio” a un “reciclado determinista”. Además, al especificar “Horas específicas” ya no se tiene en cuenta el valor de “Intervalo de tiempo regular”.

Por otro lado (y como no quiero ser un killer server), tampoco voy a poner 0 en “Tiempo de inactividad”… pero tampoco voy a dejar 5 (es más que probable que un usuario esté en mi página sin generar tráfico durante 5 minutos)… así que pondré un valor más alto (por ejemplo 20 para coincidir con el Session.Timeout).

Llegados a este punto creo tener algo más controlado cuando se reciclará mi grupo de aplicaciones, pero ¿Cómo puedo confirmar que mi nueva política de reciclaje se está llevando a cabo? Pues registrando los reciclados en el visor de eventos de Windows.

clip_image002[4]

Ahora cada vez que se recicle el grupo de aplicaciones podré consultar el visor de eventos y ver algo parecido a esto:

clip_image004[4]

clip_image006[4]

Está claro que la administración de un servidor IIS probablemente no sea tarea de un programador pero, al final, siempre acaba siendo tu tarea controlar el entorno donde se ejecuta tu aplicación y supervisar el rendimiento de la misma.

Aunque no es el propósito de este post, parece ser (no lo he comprobado) que la sección “Modelo de proceso” se puede especificar a través del fichero de configuración de nuestra aplicación (web.config) http://technet.microsoft.com/es-es/library/cc779563(v=ws.10).aspx. Sin embargo, la sección “Reciclaje” parece que no http://stackoverflow.com/questions/9697119/disable-iis7-pool-recycling-from-asp-net-config 

Por último, si quieres una referencia exacta de estas 2 secciones, puedes visitar los siguientes enlaces:

Process Model Settings for an Application Pool <processModel>

http://www.iis.net/ConfigReference/system.applicationHost/applicationPools/add/processModel

Recycling Settings for an Application Pool <recycling>

http://www.iis.net/ConfigReference/system.applicationHost/applicationPools/add/recycling

Un saludo!

8 comentarios:

  1. Veamos, entiendo que el parámetros "Intervalo de tiempo regular" hace que se reinicié el grupo de aplicaciones si o si. Pero, ¿esto podría ocurrir durante una petición (o peticiones)? Eso explicaría algunos fallos en los que se pierde la variable de sesión sin venir a cuenta...

    ResponderEliminar
  2. Hola Sergio:
    Yo creo que durante una petición no se reiniciará el grupo de aplicaciones, esperará hasta completar la petición, pero después... se reinicia seguro!
    En mi caso tengo una app con muy pocos usuarios, entonces si hay un sólo usuario conectado y se queda 5 minutos en una página sin generar tráfico en el servidor... de repente pierde la sesión y es por el valor de "Tiempo de inactividad".
    Está claro que IIS 7.5 quiere "escalar" y está claro que la session se ha vuelto un lugar "apestado" para guardar cosas, pero el kit de la cuestión es controlar "cuando se reinicia el grupo de aplicaciones".
    De hecho, también puedes "desactivar" este comportamiento si dejas a 0 tanto el valor "Intervalo de tiempo regular" y "Tiempo de inactividad". De este modo y con "Horas Específicas" (si es necesario), tú controlas cuando se reinicia el grupo de aplicaciones.
    Un saludo.

    ResponderEliminar
  3. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  4. Hola llegué a este artículo, buscando una solución a los Jobs del Quartz.Net ya que por motivo del reciclado del pool de aplicaciones no ejecutaba las tareas como debe ser, pero gracias a este artículo ya tengo una mejor idea de como manejarlo. Saludos!

    ResponderEliminar
  5. Buena información, me sirvió mucho para orientarme con problemas relacionados a los parámetros que mencionas.
    Gracias.

    ResponderEliminar
  6. Lo que ocurre es que las peticiones que ya tienen un hilo de procesos se mantienen ahí hasta que finalicen pero al reciclar se abre otro hilo de procesos para las nuevas peticiones entrantes.

    ResponderEliminar
  7. El valor 0 significa que nunca se recicla??

    ResponderEliminar