Actualice el sitio web .NET sin recargar

13

He utilizado para desarrollar sitios web en PHPy ASP classicy si algo necesitaba ser cambiado. Simplemente podría alterar uno / varios archivos y nadie realmente lo notaría. Quizás si alguien solicitara el archivo modificado durante la carga, pero eso es como medio segundo margen. Para la mayoría de los sitios más pequeños no hay problema.

Pero los sitios más recientes están construidos con C# MVCy cuando realiza cambios en el código, necesita reconstruir su sitio web y cargar los DLLarchivos alterados . Pero cuando cambie sus DLLarchivos, reiniciará su sitio web y restablecerá todos los activos sessions. También tiene que volver a cargar todo y con sitios grandes puede llevar unos minutos cargarlo todo. Todos los que navegaban por el sitio lo notarán y deberán iniciar sesión nuevamente.

Las actualizaciones importantes del sitio no son tan comunes, por lo que no es un problema. Pero tenemos actualizaciones regulares "pequeñas" para promociones. Como "Complete este formulario y obtenga tres meses de membresía gratis" o "Los primeros 10 en cargar una imagen de ... recibirán un precio". Creo que lo entenderás. Algunas promociones son similares y podrían manejarse con un módulo que muestra la información correcta según la configuración, pero a menudo requiere un código personalizado.

Estaba pensando en un sistema donde cada promoción es su propio DLLarchivo basado en una interfaz, y luego carga DLLdinámicamente usando Type.GetType, Activator.CreateInstancey InvokeMember. Aunque eso podría funcionar, me pregunto si es el camino correcto.

Entonces, mi pregunta: ¿cómo se actualiza un .NETsitio sobre la marcha, sin volver a cargar todo el sitio y sin cerrar la sesión (como el grupo de aplicaciones de reciclaje).

Hugo Delsing
fuente
En respuesta a su comentario de recompensa: los grandes sitios web en los que trabajo manejan pequeños cambios para codificar de la misma manera que manejan grandes cambios en el código: a través de equilibradores de carga y sesiones fuera del proceso, porque todo el código que se implementa para vivir necesita pasar un proceso de revisión / cierre de sesión y no podemos simplemente soltar código en los servidores. Creo que nuestras definiciones de "grande" pueden no coincidir;)
Zhaph - Ben Duguid

Respuestas:

11

Busque "Inicialización de aplicaciones" IIS 7.5, Windows 2008 R2 (más difícil de configurar) IIS 8, Windows 2012

La inicialización de la aplicación permite que cualquier aplicación (grupo de aplicaciones no sitio) reinicie para superponerse y use la anterior, aún ejecutando la aplicación anterior mientras se calienta el inicio de la nueva aplicación. Una vez que la nueva aplicación está activada (determinada por las URL que puede configurar), comenzará a usar la nueva aplicación y cerrará la anterior. El uso de la Inicialización de aplicaciones junto con métodos para garantizar que la sesión permanezca en todos los reinicios del grupo de aplicaciones puede permitir que su sitio se reinicie sin problemas. (Zhaph tiene una buena nota sobre la clave de la máquina).

Además de los enlaces anteriores para la configuración de Inicialización de la aplicación, querrá ver qué desencadena un reinicio del sitio, ya que el reinicio del sitio no usa la Iniciación de la aplicación, el reinicio del sitio no será perfecto.

Puede configurar IIS para que una actualización de DLL no active inmediatamente el reinicio del sitio, ni cambie a web.config (valores altos de ChangeNotification en httpRuntime y archivos de configuración externos, según corresponda a su sitio).

El resultado final es que puede actualizar las DLL / código sin reiniciar el sitio, luego forzar un reinicio de la aplicación que utilizará el calentamiento de fondo de AppInitialization para el cambio de código sin interrupciones.

Hacer estas cosas en concierto funciona bastante bien para reinicios sin problemas.

jeffreypriebe
fuente
Un buen conjunto de pasos allí, ciertamente algo a tener en cuenta :)
Zhaph - Ben Duguid
Esto suena como lo que estaba buscando. Voy a intentarlo y configurarlo. Gracias
Hugo Delsing
@HugoDelsing Espero que funcione bien para ti.
jeffreypriebe
Gracias, esto es lo que terminé usando y funciona muy bien.
Hugo Delsing
@HugoDelsing Me alegra saber que también funcionó para ti.
jeffreypriebe
5

Hay varias formas de manejar lo que está pidiendo, y algunos aspectos diferentes a su pregunta:

Maneje pequeñas actualizaciones para promociones

Lo que realmente está buscando aquí es un sistema de administración de contenido o similar que le permita editar el contenido sobre la marcha (piense en Wordpress / Drupal o desde un punto de vista de .NET N2 CMS, Umbraco, Orchard, etc.), sin embargo allí Hay algunas cosas que podrías probar si no has seguido esa ruta.

Debido a que ASP.NET solo se recarga realmente si toca ciertos tipos de archivos (web.config (s), el contenido de las carpetas /bin/y en /app_code/su mayoría) y tiene un límite configurable para "otros cambios de archivos" (básicamente, una vez que lo ha modificado) muchos archivos dentro de su sitio el grupo de aplicaciones se reiniciará - NumRecompilesBeforeAppRestart) podría hacer algo en lo que verifica una carpeta diferente para algunos .htmlarchivos estáticos (es decir ) que extrae y muestra según sea necesario, o utilice el LoadControlmétodo que toma una ruta de cadena para un .ascxcontrol de usuario y lo carga dinámicamente: cómo determinar qué mostrar es una pregunta diferente más adecuada para StackOverflow; sin embargo, recomendaría una solución basada en convenciones de nomenclatura.

También podría considerar el uso de algo como el Marco de Extensibilidad Administrada (MEF, que ha sido una parte completa del marco .NET desde la versión 4) que le permite escribir una arquitectura basada en complementos y especificar una carpeta fuera de su /bin/directorio para monitorear nuevos .DLL: aunque no lo he intentado para ver si evitará el problema de reinicio de la aplicación, lo he usado con buenos resultados en un entorno web para agregar funcionalidad común a un sitio.

Si eso no resulta atractivo, la única otra opción que se me ocurre sería agregar los controles como "código frontal" como lo hicimos en ASP clásico, es decir, con un <script runat="server">bloque en lugar de una clase compilada "código subyacente" que contiene la lógica para ejecutar el control: esto eliminará la necesidad de un cambio de DLL, a expensas de alguna pérdida de rendimiento por primera vez a medida que el control se compila sobre la marcha, nuevamente deberá equilibrar esto con el NumRecompilesBeforeAppRestartsi Estás haciendo muchos pequeños cambios.

¿Cómo persisto las sesiones en los reinicios de la aplicación?

Este es posiblemente un problema más fácil de resolver e implica tres pasos clave:

  1. Configure MachineKey (IIS7, pero aún se mantiene para 8) para que sea un valor constante en lugar de AutoGenerate- esto significa que cuando AppPool recicle utilizará la misma clave, y así podrá descifrar las cookies de sesión, viewstate, etc. de antes El reciclaje.
  2. O bien configurar un servidor de estado o configurar una base de datos para mantener el estado de sesión .
  3. Cambiar el uso InProcde StateServero SQLServeren el elemento SessionState en su web.config.

De esta manera, tendrá sesiones persistentes que sobrevivirán al reinicio de una aplicación. Sin embargo, estos no son "gratuitos": todo lo que almacene en la sesión ahora debe ser serializable, e incurrirá en un ligero impacto en el rendimiento ya que cada carga de la página ahora requerirá viajes de red adicionales para obtener y potencialmente liberar los datos de la sesión.

Sin embargo, si se encuentra en una posición en la que la aplicación tarda "varios minutos" en reiniciarse después de una implementación, es posible que desee considerar la posibilidad de pasar a un entorno de carga equilibrada o, al menos, a una configuración por etapas / en vivo intercambiable en caliente (como el proporcionado por Azure / AWS / etc.): de esta manera, puede desconectar un servidor mientras lo actualiza o prepararlo con el nuevo código y luego intercambiarlo, siempre que haya tomado los pasos para abordar sesiones (ver arriba) esto funcionará bien sin impacto para sus usuarios.

Zhaph - Ben Duguid
fuente
Gracias por tu larga respuesta. Lamentablemente CMSno es lo que quiero. No quiero alterar el contenido, quiero alterar el código. La parte sobre las sesiones fue solo un ejemplo. Cambiarlo no resolverá el problema de que el sitio esté inactivo durante un minuto o dos cuando está recargando DLLarchivos. La MEFparte fue interesante, pero es una solución de terceros para el sistema en el que estaba pensando. Entonces +1 por el esfuerzo, pero desafortunadamente no es realmente una respuesta a mi pregunta.
Hugo Delsing
1
He actualizado mi respuesta para abordar algunos de esos puntos: MEF fue lanzado por MS y ha sido una parte completa del marco .NET desde la v4. Puede intentar usar el código frontal para sus nuevos controles, alternativamente, adoptar una configuración de carga equilibrada / puesta en escena que permita poner en marcha un servidor y luego intercambiarlo.
Zhaph - Ben Duguid
1
He esbozado una solución alternativa usando la inicialización de la aplicación. La ventaja es que todo el código y la configuración del servidor son "normales" sin un equilibrio de carga especial o controles de carga dinámicos, lo que simplifica el entorno de ejecución. Por supuesto, una configuración de equilibrio de carga / puesta en escena en vivo puede ser útil por otros motivos.
jeffreypriebe