Cómo implementar un ASP.NET Aplicación con cero tiempo de inactividad


Para desplegar una nueva versión de nuestro sitio web hacemos lo siguiente:

  1. Comprime el nuevo código y súbelo al servidor.
  2. En el servidor live, elimine todo el código live del directorio del sitio web de IIS.
  3. Extraiga el nuevo código zipfile en el directorio IIS ahora vacío

Este proceso es todo scripted, y sucede bastante rápidamente, pero todavía puede haber un tiempo de inactividad de 10-20 segundos cuando se eliminan los archivos antiguos, y los archivos nuevos son desplegar.

¿Alguna sugerencia sobre un método de tiempo de inactividad de 0 segundos?

Author: Sklivvz, 2008-09-29

11 answers

Necesita 2 servidores y un equilibrador de carga. Aquí está en pasos:

  1. Activar todo el tráfico en el servidor 2
  2. Desplegar en el servidor 1
  3. Servidor de prueba 1
  4. Activar todo el tráfico en el servidor 1
  5. Desplegar en el servidor 2
  6. Servidor de prueba 2
  7. Girar el tráfico en ambos servidores

La cosa es que, incluso en este caso, todavía tendrá reinicios de aplicaciones y pérdida de sesiones si está utilizando "sticky sessions". Si tiene sesiones de base de datos o un servidor de estado, entonces todo debería estar bien.

 76
Author: Sklivvz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-29 09:35:03

El Microsoft Web Deployment Tool soporta esto hasta cierto punto:

Habilita el Archivo Transaccional de Windows Soporte del sistema (TxF). Cuando soporte TxF está habilitado, las operaciones de archivo son atómico; es decir, o bien tienen éxito o fallar completamente. Esto garantiza los datos integridad y evita datos o archivos de existir en un "medio camino" o estado corrupto. En MS Deploy, TxF es desactivado de forma predeterminada.

Parece que la transacción es para toda la sincronización. También, TxF es una característica de Windows Server 2008, por lo que esta característica de transacción no funcionará con versiones anteriores.

Creo que es posible modificar su script para 0-downtime usando carpetas como versiones y la metabase de IIS:

  • para una ruta/url existente:
  • Copiar sitio web nuevo (o modificado) al servidor bajo
    • \ web \ app \ v2. 1 \
  • Modificar la metabase de IIS para cambiar la ruta del sitio web
    • desde \web \ app \ 2.0 \ {[18]]}
    • a \web \ app \ v2. 1 \

Este método ofrece los siguientes beneficios:

  • En el caso de que la nueva versión tenga un problema, puede revertir fácilmente a v2. 0
  • Para implementar en varios servidores físicos o virtuales, puede usar su script para la implementación de archivos. Una vez que todos los servidores nueva versión, puede cambiar simultáneamente todas las metabases de servidores utilizando la herramienta de implementación web de Microsoft.
 59
Author: George Tsiokos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-23 13:44:58

Puede lograr una implementación sin tiempo de inactividad en un solo servidor utilizando el enrutamiento de solicitudes de aplicaciones en IIS como un equilibrador de carga de software entre dos sitios locales de IIS en puertos diferentes. Esto se conoce como una estrategia de despliegue azul verde donde solo uno de los dos sitios está disponible en el balanceador de carga en un momento dado. Implementar en el sitio que está "abajo", calentarlo y llevarlo al balanceador de carga (generalmente pasando una comprobación de estado de enrutamiento de solicitud de aplicación), luego tomar el sitio original que estaba arriba, fuera de la "piscina" (de nuevo haciendo que su comprobación de estado falle).

Un tutorial completo se puede encontrar aquí.

 9
Author: kavun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-08 06:04:01

Pasé por esto recientemente y la solución que se me ocurrió fue tener dos sitios configurados en IIS y cambiar entre ellos.

Para mi configuración, tenía un directorio web para cada sitio A y B como este: c:\Intranet\Live Una interfaz\ c:\Intranet\Live B \ Interfaz

En IIS, tengo dos sitios idénticos (mismos puertos, autenticación, etc.) cada uno con su propio grupo de aplicaciones. Uno de los sitios se está ejecutando (A) y el otro se detiene (B). el live one también tiene el anfitrión en vivo cabecera.

Cuando se trata de implementar en vivo, simplemente publico en la ubicación del sitio DETENIDO. Debido a que puedo acceder al sitio B usando su puerto, puedo precalentar el sitio para que el primer usuario no provoque el inicio de una aplicación. Luego, usando un archivo por lotes, copio el encabezado del host en vivo a B, detengo A e inicio B.

 7
Author: Rob King,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-19 02:39:24

Usando Microsoft.Web.Clase ServerManager de la administración puede desarrollar su propio agente de implementación.

El truco es cambiar la ruta física del directorio VirtualDirectory, lo que resulta en un cambio atómico en línea entre aplicaciones web antiguas y nuevas.

Tenga en cuenta que esto puede resultar en AppDomains antiguos y nuevos que se ejecutan en paralelo!

El problema es cómo sincronizar los cambios a las bases de datos, etc.

Sondeando la existencia de AppDomains con antiguos o nuevos PhysicalPaths es posible detectar cuando el antiguo dominio de aplicación(s) que han terminado, y si el nuevo dominio de aplicación(s) han puesto en marcha.

Para forzar el inicio de un AppDomain, debe realizar una solicitud HTTP (IIS 7.5 admite la función de inicio automático)

Ahora necesita una forma de bloquear las solicitudes para el nuevo AppDomain. Utilizo un mutex llamado, que es creado y propiedad del agente de implementación, esperado por el Application_Start de la nueva aplicación web y luego liberado por el agente de implementación una vez que las actualizaciones de la base de datos han hecho.

(Uso un archivo de marcador en la aplicación web para habilitar el comportamiento de espera mutex) Una vez que se ejecuta la nueva aplicación web, elimino el archivo de marcador.

 6
Author: Jack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-07 13:31:28

OK así que ya que todo el mundo está rechazando la respuesta que escribí en 2008*...

Les diré cómo lo hacemos ahora en 2014. Ya no utilizamos Sitios Web porque estamos utilizando ASP.NET MVC ahora.

Ciertamente no necesitamos un equilibrador de carga y dos servidores para hacerlo, eso está bien si tiene 3 servidores para cada sitio web que mantiene, pero es un exceso total para la mayoría de los sitios web.

Además, no dependemos del último asistente de Microsoft, demasiado lento y demasiada magia oculta, y demasiado propenso a cambiar su nombre.

Así es como lo hacemos:

  1. Tenemos un paso de compilación post que copia los archivos DLL generados en una carpeta 'bin-pub'.

  2. Usamos Beyond Compare (que es excelente**) para verificar y sincronizar archivos modificados (a través de FTP porque es ampliamente compatible) hasta el servidor de producción

  3. Tenemos una URL segura en el sitio web que contiene un botón que copia todo en ' bin-pub 'a' bin ' (tomando una copia de seguridad primero para habilitar retroceso rápido). En este punto, la aplicación se reinicia. Luego, nuestro OR comprueba si hay tablas o columnas que deban agregarse y las crea.

Eso es solo un tiempo de inactividad de milisegundos. El reinicio de la aplicación puede tardar uno o dos segundos, pero durante el reinicio las solicitudes se almacenan en búfer, por lo que efectivamente no hay tiempo de inactividad.

Todo el proceso de implementación tarda de 5 segundos a 30 minutos, dependiendo de cuántos archivos se cambien y cuántos cambios se revisen.

De esta manera no tiene que copiar un sitio web completo a un directorio diferente, sino solo a la carpeta bin. También tiene un control completo sobre el proceso y sabe exactamente lo que está cambiando.

**Siempre hacemos un vistazo rápido de los cambios que estamos implementando, como una doble comprobación de último minuto, para que sepamos qué probar y si algo se rompe, estamos listos. Usamos Beyond Compare porque te permite fácilmente diferenciar archivos a través de FTP. Nunca haría esto sin BC, no tienes idea de lo que eres sobrescribir.

*Desplácese hasta la parte inferior para verlo :( Por cierto, ya no recomendaría Sitios Web porque son más lentos de construir y pueden fallar mal con la mitad de los archivos temporales compilados. Los usamos en el pasado porque permitían una implementación más ágil de archivo por archivo. Muy rápido para solucionar un problema menor y se puede ver exactamente lo que está implementando (si utiliza Beyond Compare, por supuesto, de lo contrario olvídelo).

 6
Author: mike nelson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-09 12:01:30

Los únicos métodos de tiempo de inactividad cero que se me ocurren incluyen alojamiento en al menos 2 servidores.

 5
Author: Sam Meldrum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-29 09:29:52

Me gustaría refinar un poco la respuesta de George, como sigue, para un solo servidor:

  1. Utilice un Proyecto de Implementación Web para precompilar el sitio en una única DLL
  2. Comprime el nuevo sitio y súbelo al servidor
  3. Descomprimirlo en una nueva carpeta ubicada en una carpeta con los permisos correctos para el sitio, por lo que los archivos descomprimidos heredan los permisos correctamente (tal vez e:\web, con subcarpetas v20090901, v20090916, etc)
  4. Utilice el administrador de IIS para cambiar el nombre de la carpeta que contiene el sitio
  5. Mantenga la carpeta antigua por un tiempo, para que pueda recurrir a ella en caso de problemas

El paso 4 hará que el proceso de trabajo de IIS se recicle.

Esto solo es cero tiempo de inactividad si no está utilizando sesiones InProc; use el modo SQL en su lugar si puede (mejor aún, evite el estado de la sesión por completo).

Por supuesto, es un poco más complicado cuando hay varios servidores y/o cambios en la base de datos....

 1
Author: RickNZ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-15 17:11:06

Para ampliar la respuesta de sklivvz, que dependía de tener algún tipo de balanceador de carga (o simplemente una copia en espera en el mismo servidor)

  1. Dirigir todo el tráfico al Sitio / Servidor 2
  2. Opcionalmente, espere un poco, para asegurarse de que el menor número posible de usuarios tengan flujos de trabajo pendientes en la versión implementada
  3. Implementar en el Sitio / Servidor 1 y calentarlo tanto como sea posible
  4. Ejecuta las migraciones de bases de datos transaccionalmente (esfuérzate por hacer esto posible)
  5. Dirigir inmediatamente todos tráfico al Sitio / Servidor 1
  6. Desplegar en el Sitio / Servidor 2
  7. Tráfico directo a ambos sitios/servidores

Es posible introducir un poco de prueba de humo, creando una instantánea/copia de la base de datos, pero eso no siempre es factible.

Si es posible y necesario, use "diferencias de enrutamiento", como diferentes URL de tenant: s (customerX.myapp.net) o diferentes usuarios, para desplegar a un grupo desconocido de conejillos de indias primero. Si nada falla, libera a todos.

Desde la base de datos las migraciones están involucradas, retroceder a una versión anterior a menudo es imposible.

Hay formas de hacer que las aplicaciones se reproduzcan mejor en estos escenarios, como el uso de colas de eventos y mecanismos de reproducción, pero ya que estamos hablando de implementar cambios en algo que está en uso, realmente no hay una manera infalible.

 1
Author: gliljas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-15 00:06:54

Así es como lo hago:

Requisitos mínimos absolutos del sistema:
1 servidor con

  • 1 balanceador de carga/proxy inverso (por ejemplo, nginx) que se ejecuta en el puerto 80
  • 2 ASP. NET-Core / mono reverse-proxy / fastcgi chroot-jails o docker-containers escuchando en 2 puertos TCP diferentes
    (o incluso solo dos aplicaciones de proxy inverso en 2 puertos TCP diferentes sin ningún sandbox)

Flujo de trabajo:

Iniciar transacción myupdate

try
    Web-Service: Tell all applications on all web-servers to go into primary read-only mode 
    Application switch to primary read-only mode, and responds 
    Web sockets begin notifying all clients 
    Wait for all applications to respond

    wait (custom short interval)

    Web-Service: Tell all applications on all web-servers to go into secondary read-only mode 
    Application switch to secondary read-only mode (data-entry fuse)
    Updatedb - secondary read-only mode (switches database to read-only)

    Web-Service: Create backup of database 
    Web-Service: Restore backup to new database
    Web-Service: Update new database with new schema 

    Deploy new application to apt-repository 
    (for windows, you will have to write your own custom deployment web-service)
    ssh into every machine in array_of_new_webapps
    run apt-get update
    then either 
    apt-get dist-upgrade
    OR
    apt-get install <packagename>
    OR 
    apt-get install --only-upgrade <packagename>
    depending on what you need
    -- This deploys the new application to all new chroots (or servers/VMs)

    Test: Test new application under test.domain.xxx
    -- everything that fails should throw an exception here
    commit myupdate;

    Web-Service: Tell all applications to send web-socket request to reload the pages to all clients at time x (+/- random number)
    @client: notify of reload and that this causes loss of unsafed data, with option to abort 

    @ time x:  Switch load balancer from array_of_old_webapps to array_of_new_webapps 
    Decomission/Recycle array_of_old_webapps, etc.

catch
        rollback myupdate 
        switch to read-write mode
        Web-Service: Tell all applications to send web-socket request to unblock read-only mode
end try 
 1
Author: Stefan Steiger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-28 09:26:53

Yo sugeriría mantener los archivos antiguos allí y simplemente sobrescribirlos. De esta manera, el tiempo de inactividad se limita a tiempos de sobrescritura de un solo archivo y solo falta un archivo a la vez.

Sin embargo, no estoy seguro de que esto ayude en una "aplicación web" (creo que estás diciendo que eso es lo que estás usando), por lo que siempre usamos "sitios web". También con la implementación de" sitios web " no reinicia su sitio y elimina todas las sesiones de usuario.

 -7
Author: mike nelson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-20 09:07:01