Minimizar el impacto de subidas a producción (waitChangeNotification, maxWaitChangeNotification)

A pesar de que no es recomendado, muchas veces nos hemos visto forzados a subir cambios a producción “en caliente.”


Estos cambios en caliente generalmente se deben por cambios en machine.config, web.config o el copiado de nuevos assemblies a la carpeta bin, y estos cambios obligan a que se reinicie el dominio  de la aplicación asp.net.


Como dominio de aplicación entendemos una estructura interna en memoria, dentro de un proceso, donde están cargados los assemblies, las páginas compiladas y toda la memoria utilizada en el funcionamiento de nuestra aplicación. Esta explicación es muy pobre, pero contiene lo necesario para entender el costo de los cambios.


Cada vez que se inicia o carga un dominio, previamente se debe descargar, esto es, suponiendo que no es la primera vez que se inicia. Y antes de poder descargarse, debe terminar de procesar todos los requerimientos que tiene activos.


Debido a lo anterior, cada vez que copiamos assemblies a la carpeta bin, disparamos una descarga del dominio. Si en ese momento entra un nuevo requerimiento, se crea un nuevo dominio para atender el requerimiento (con el o los nuevos assemblies que hayan disponibles producto de la copia). Sucesivas copias en el mismo período de tiempo hará que la situación se repita. Esto último puede llevar a nuestro servidor y aplicación a quedar en un estado inestable.


Personalmente lo he vivido varias veces, cuando se sube en caliente para corregir bugs críticos que no pueden esperar. Dentro de los errores recibidos producto de estas subidas extremas, estaba un extraño error de compilación de las páginas. Generalmente, la única manera de resolver la inestabilidad era haciendo un iisreset.


Si hacemos un resumen de cuánto tiempo perdíamos en esas subidas, generalmente era entre 30 y 45 segundos. No vamos a hablar ahora de las molestias a los clientes. Primero por una aplicación que respondía inestablemente y luego por que definitivamente no prestábamos servicio.


Para minimizar este problema y “garantizar” que el impacto de una subida a producción sea mínimo, existen un par de opciones disponibles para configurar en el archivo web.config. Por favor, notar que utilicé comillas en garantizar. Esto debido a que si se configuran mal las opciones, el resultado no es el mejor (aunque mejor que el escenario anterior sin la configuración).


Estas opciones son waitChangeNotification y maxWaitChangeNotification. La documentación oficial de estos contadores está en http://msdn2.microsoft.com/es-es/library/e1f13641(VS.80).aspx, pero la calidad de la explicación es bastante pobre.

Vamos a hacer un mejor esfuerzo.

Aclaremos primero que ambas almacenan valores en segundos y a pesar de que la documentación dice que es un atributo sólo de aspnet 2.0, en la versión 1.1 también funciona (al menos en mi XP Pro con IIS 5.1, y la aplicación web configurada en 1.1)


La primera opción de configuración (waitChangeNotification) instruye al IIS y aspnet cuanto tiempo debe esperar a que un nuevo requerimiento genere un nuevo dominio una vez que ha detectado un cambio.


Esto nos ayuda a darnos un rango de tiempo para poder copiar todos los archivos necesarios. Este rango de tiempo es desplazable, lo que significa que son X segundos después de la última notificación de cambio (último archivo subido/modificado/agregado), descartando todas las notificaciones anteriores.


La segunda opción (maxWaitChangeNotification) establece el tiempo máximo en que se reiniciará el dominio. Esta opción existe ya que como la anterior es desplazable, sucesivos cambios en un breve tiempo podrían demorar el reinicio del dominio más de lo esperable.


Veamos un ejemplo para aclarar esto.

Ejemplo

Configurando el primer atributo en 5 segundos, si realizo 10 modificaciones en total, cada una separada 4 segundos de la modificación anterior, el reinicio se realizaría a los 41 segundos, sólo 5 segundos después de la última modificación. Esta última ocurre a los 36 segundos ya que la primera ocurre a los 0 segundos (0-4-8-12-16-20-24-28-32-36).


La segunda opción de configuración, si se define en 30 segundos, implicaría que el escenario anterior nunca ocurra ya que habría forzado el reinicio a los 30 segundos, entre la 8va y 9na modificación.


Con esta segunda opción, el segundo reinicio sería a los 11 segundos después, suponiendo que el reinicio es instantáneo.

De vuelta a la realidad

A pesar de que el ejemplo anterior puede parecer complejo, no dejes que éste te confunda. Lo importante es darle un tiempo a tu aplicación para que se reinicie limpiamente sin afectar demasiado a los clientes. Elije un tiempo acorde a las necesidades de tu aplicación y configura las dos opciones, no sólo la primera, y la segunda debe ser mayor a la primera.


¿Cómo se modifica en el web.config?
<system.web>
<
httpRuntime waitChangeNotification=X maxWaitChangeNotification=Y/>
</system.web>


Saludos,
Patrick

One Reply to “Minimizar el impacto de subidas a producción (waitChangeNotification, maxWaitChangeNotification)”

  1. Muy buena la explicación, generalmente me encuentro con personas que consultan acerca de este tipo de escenarios, la mayoria opta por el famoso restart.

    saludos cordiales.

Leave a Reply

Your email address will not be published. Required fields are marked *