Pregunta

Para implementar 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 en vivo, elimine todo el código en vivo del directorio del sitio web de IIS.
  3. Extraiga el nuevo archivo zip de código en el directorio IIS ahora vacío

Todo este proceso está programado y se realiza con bastante rapidez, pero aún puede haber un tiempo de inactividad de 10 a 20 segundos cuando se eliminan los archivos antiguos y se implementan los nuevos.

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

¿Fue útil?

Solución

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

  1. Encienda todo el tráfico en el servidor 2
  2. Implementar en el servidor 1
  3. Servidor de prueba 1
  4. Convertir todo el tráfico en el servidor 1
  5. Implementar en el servidor 2
  6. Servidor de prueba 2
  7. Encienda el tráfico en ambos servidores

La cosa es que, incluso en este caso, aún tendrá reinicios de la aplicación y pérdida de sesiones si está utilizando " sesiones fijas " ;. Si tiene sesiones de base de datos o un servidor de estado, todo debería estar bien.

Otros consejos

El La herramienta de implementación web de Microsoft admite esto hasta cierto punto:

  

Habilita el archivo transaccional de Windows   Sistema de soporte (TxF). Cuando soporte TxF   está habilitado, las operaciones de archivo son   atómico; es decir, tienen éxito   o fallar completamente. Esto asegura los datos   Integridad y evita datos o archivos.   de existir en un "medio camino" o   Estado corrupto. En MS Deploy, TxF es   desactivado por defecto.

Parece que la transacción es para toda la sincronización. Además, 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 tiempo de inactividad 0 usando carpetas como versiones y la metabase de IIS:

  • para una ruta / url existente:
  • Copie el sitio web nuevo (o modificado) al servidor bajo
    • \ web \ app \ v2.1 \
  • Modificar la metabase de IIS para cambiar la ruta del sitio web
    • de \ web \ app \ 2.0 \
    • a \ web \ app \ v2.1 \

Este método ofrece los siguientes beneficios:

  • En caso de que la nueva versión tenga un problema, puede retroceder fácilmente a v2.0
  • Para implementar en múltiples servidores físicos o virtuales, puede usar su script para la implementación de archivos. Una vez que todos los servidores tengan la nueva versión, puede cambiar simultáneamente las metabases de todos los servidores con la Herramienta de implementación web de Microsoft.

Puede lograr una implementación sin tiempo de inactividad en un solo servidor utilizando el enrutamiento de solicitud de aplicaciones en IIS como un equilibrador de carga de software entre dos sitios de IIS locales en diferentes puertos. Esto se conoce como una estrategia de implementación verde azul donde solo uno de los dos sitios está disponible en el equilibrador de carga en un momento dado. Implemente en el sitio que está `` inactivo '', caliéntelo y llévelo al equilibrador de carga (generalmente pasando una verificación de estado de Enrutamiento de solicitud de aplicación), luego saque el sitio original que estaba arriba, fuera del grupo ``. (de nuevo, haciendo que su chequeo de salud falle).

Puede encontrar un tutorial completo aquí.

Revisé 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 A \ Interface c: \ Intranet \ Live B \ Interface

En IIS, tengo dos sitios idénticos (los 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 también tiene el encabezado del host en vivo.

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

Utilizando la clase ServerManager de Microsoft.Web.Administration, puede desarrollar su propio agente de implementación.

El truco consiste en cambiar PhysicalPath de VirtualDirectory, lo que resulta en un cambio atómico en línea entre las aplicaciones web antiguas y nuevas.

¡Tenga en cuenta que esto puede resultar en que se ejecuten AppDomains viejos y nuevos en paralelo!

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

Al sondear la existencia de AppDomains con PhysicalPaths antiguos o nuevos, es posible detectar cuándo han finalizado los AppDomain anteriores, y si se han iniciado los nuevos AppDomain.

Para forzar que se inicie un dominio de aplicación, debe realizar una solicitud HTTP (IIS 7.5 es compatible con la función de inicio automático)

Ahora necesita una forma de bloquear solicitudes para el nuevo dominio de aplicación. Utilizo una exclusión mutua con nombre, creada y propiedad del agente de implementación, esperada por la Application_Start de la nueva aplicación web y luego liberada por el agente de implementación una vez que se han realizado las actualizaciones de la base de datos.

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

Está bien, ya que todos están votando de forma negativa la respuesta que escribí en 2008 * ...

Le diré cómo lo hacemos ahora en 2014. Ya no usamos sitios web porque estamos usando ASP.NET MVC ahora.

Ciertamente no necesitamos un equilibrador de carga y dos servidores para hacerlo, 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 confiamos en el último asistente de Microsoft: demasiado lento, demasiada magia oculta y demasiado propenso a cambiar su nombre.

Así es como lo hacemos:

  1. Tenemos un paso posterior a la compilación que copia los DLL generados en una carpeta 'bin-pub'.

  2. Utilizamos Beyond Compare (que es excelente **) para verificar y sincronizar los 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' (tomar una copia de seguridad primero para permitir una reversión rápida). En este punto, la aplicación se reinicia sola. Luego, nuestro ORM verifica si hay tablas o columnas que deben agregarse y las crea.

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

El proceso de implementación completo toma 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 control completo sobre el proceso y sabe exactamente qué está cambiando.

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

* 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 los archivos temporales compilados a medias. Los usamos en el pasado porque permitían archivos más ágiles. implementación por archivo. Muy rápido para solucionar un problema menor y puede ver exactamente lo que está implementando (si usa Beyond Compare, por supuesto, de lo contrario, olvídelo).

Los únicos métodos de tiempo de inactividad cero en los que puedo pensar incluyen el alojamiento en al menos 2 servidores.

Refinaría un poco la respuesta de George, como sigue, para un solo servidor:

  1. Use un proyecto de implementación web para precompilar el sitio en una sola DLL
  2. Comprime el nuevo sitio y súbelo al servidor
  3. Descomprímalo en una nueva carpeta ubicada en una carpeta con los permisos adecuados para el sitio, por lo que los archivos descomprimidos heredan los permisos correctamente (tal vez e: \ web, con subcarpetas v20090901, v20090916, etc.)
  4. Use 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 es solo cero tiempo de inactividad si no está utilizando sesiones InProc; use el modo SQL en su lugar si puede (aún mejor, evite el estado de sesión por completo).

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

Para ampliar la respuesta de sklivvz, que se basaba en tener algún tipo de equilibrador 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 la menor cantidad posible de usuarios tenga flujos de trabajo pendientes en la versión implementada
  3. Implemente en el sitio / servidor 1 y caliéntelo tanto como sea posible
  4. Ejecutar migraciones de bases de datos transaccionalmente (esforzarse por hacer esto posible)
  5. Dirija inmediatamente todo el tráfico al Sitio / Servidor 1
  6. Implementar en el sitio / servidor 2
  7. Tráfico directo a ambos sitios / servidores

Es posible introducir un poco de pruebas de humo mediante la creación de una instantánea / copia de la base de datos, pero eso no siempre es posible.

Si es posible y necesario, use "diferencias de enrutamiento", como la URL del inquilino diferente: s (customerX.myapp.net) o diferentes usuarios, para desplegar primero en un grupo desconocido de cobayas. Si nada falla, libéralo a todos.

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

Hay formas de hacer que las aplicaciones se desempeñen 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 ninguna manera a prueba de errores.

Así es como lo hago:

Requisitos mínimos absolutos del sistema:
 1 servidor con

  • 1 equilibrador 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 escuchan 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 

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

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top