Domanda

Per distribuire una nuova versione del nostro sito Web facciamo quanto segue:

  1. Comprimi il nuovo codice e caricalo sul server.
  2. Sul server live, eliminare tutto il codice live dalla directory del sito Web IIS.
  3. Estrai il nuovo codice zipfile nella directory IIS ora vuota

Questo processo è tutto scriptato e si svolge abbastanza rapidamente, ma possono esserci ancora tempi di inattività di 10-20 secondi quando i vecchi file vengono eliminati e i nuovi file vengono distribuiti.

Qualche suggerimento su un metodo di downtime di 0 secondi?

È stato utile?

Soluzione

Sono necessari 2 server e un bilanciamento del carico. Ecco i passaggi:

  1. Attiva tutto il traffico sul Server 2
  2. Distribuisci sul server 1
  3. Test Server 1
  4. Attiva tutto il traffico sul Server 1
  5. Distribuisci sul server 2
  6. Test Server 2
  7. Attiva il traffico su entrambi i server

Il fatto è che, anche in questo caso, avrai comunque il riavvio dell'applicazione e la perdita di sessioni se stai utilizzando "sessioni appiccicose". Se hai sessioni di database o un server di stato, allora tutto dovrebbe andare bene.

Altri suggerimenti

Il Microsoft Web Deployment Tool lo supporta in una certa misura:

  

Abilita il file transazionale di Windows   Supporto di sistema (TxF). Quando il supporto TxF   è abilitato, le operazioni sui file sono   atomico; cioè, o ci riescono   o fallire completamente. Questo assicura i dati   integrità e impedisce dati o file   dall'esistere in una "metà strada" o   stato corrotto. In MS Deploy, TxF è   disabilitato per impostazione predefinita.

Sembra che la transazione sia per l'intera sincronizzazione. Inoltre, TxF è una funzionalità di Windows Server 2008, quindi questa funzionalità di transazione non funzionerà con le versioni precedenti.

Credo che sia possibile modificare lo script per 0 downtime utilizzando le cartelle come versioni e la metabase IIS:

  • per un percorso / url esistente:
  • Copia il nuovo sito Web (o modificato) sul server in
    • \ web \ app \ v2.1 \
  • Modifica la metabase IIS per cambiare il percorso del sito Web
    • da \ web \ app \ 2.0 \
    • Da
    • a \ web \ app \ v2.1 \

Questo metodo offre i seguenti vantaggi:

  • Nel caso in cui la nuova versione abbia un problema, è possibile eseguire facilmente il rollback alla v2.0
  • Per distribuire su più server fisici o virtuali, è possibile utilizzare lo script per la distribuzione di file. Una volta che tutti i server hanno la nuova versione, è possibile modificare contemporaneamente tutte le metabase dei server utilizzando lo strumento di distribuzione Web Microsoft.

È possibile ottenere una distribuzione dei tempi di inattività pari a zero su un singolo server utilizzando il routing delle richieste dell'applicazione in IIS come bilanciamento del carico software tra due siti IIS locali su porte diverse. Questa è nota come strategia di implementazione verde blu in cui solo uno dei due siti è disponibile nel bilanciamento del carico in un determinato momento. Distribuire sul sito che è "inattivo", riscaldarlo e portarlo nel bilanciamento del carico (di solito passando un controllo dello stato di routing della richiesta dell'applicazione), quindi prendere il sito originale che era attivo, fuori dal "pool". (di nuovo fallendo il controllo dello stato).

Un tutorial completo può essere trovato qui.

L'ho esaminato di recente e la soluzione che mi è venuta in mente è stata quella di creare due siti in IIS e passare da uno all'altro.

Per la mia configurazione, avevo una directory web per ogni sito A e B come questa: c: \ Intranet \ Live A \ Interface c: \ Intranet \ Live B \ Interface

In IIS, ho due siti identici (stesse porte, autenticazione ecc.) ciascuno con il proprio pool di applicazioni. Uno dei siti è in esecuzione (A) e l'altro viene arrestato (B). quello live ha anche l'intestazione host live.

Quando si tratta di distribuire per vivere, pubblico semplicemente nella posizione del sito STOPPED. Poiché posso accedere al sito B utilizzando la sua porta, posso preriscaldare il sito in modo che il primo utente non causi l'avvio di un'applicazione. Quindi, utilizzando un file batch, copio l'intestazione host live su B, interrompo A e avvio B.

Utilizzando la classe ServerManager di Microsoft.Web.Administration è possibile sviluppare il proprio agente di distribuzione.

Il trucco è cambiare PhysicalPath di VirtualDirectory, che si traduce in un passaggio atomico online tra vecchie e nuove app Web.

Tieni presente che ciò può comportare l'esecuzione in parallelo di vecchi e nuovi AppDomain!

Il problema è come sincronizzare le modifiche ai database ecc.

Effettuando il polling per l'esistenza di AppDomain con PhysicalPaths vecchi o nuovi, è possibile rilevare quando i vecchi AppDomain sono stati chiusi e se i nuovi AppDomain sono stati avviati.

Per forzare l'avvio di AppDomain è necessario effettuare una richiesta HTTP (IIS 7.5 supporta la funzione di avvio automatico)

Ora hai bisogno di un modo per bloccare le richieste per il nuovo AppDomain. Uso un mutex denominato, creato e di proprietà dell'agente di distribuzione, atteso da Application_Start della nuova app Web e quindi rilasciato dall'agente di distribuzione una volta effettuati gli aggiornamenti del database.

(utilizzo un file marker nell'app Web per abilitare il comportamento di attesa mutex) Quando la nuova app Web è in esecuzione, elimino il file marker.

OK, dato che tutti stanno votando a fondo la risposta che ho scritto nel 2008 * ...

Ti dirò come lo facciamo ora nel 2014. Non utilizziamo più i siti Web perché stiamo utilizzando ASP.NET MVC ora.

Certamente non abbiamo bisogno di un bilanciamento del carico e di due server per farlo, va bene se hai 3 server per ogni sito web che gestisci ma è eccessivo per la maggior parte dei siti web.

Inoltre, non facciamo affidamento sull'ultima procedura guidata di Microsoft: troppo lenta, troppa magia nascosta e troppo incline a cambiarne il nome.

Ecco come lo facciamo:

  1. Abbiamo un passaggio post build che copia le DLL generate in una cartella 'bin-pub'.

  2. Usiamo Beyond Compare (che è eccellente **) per verificare e sincronizzare i file modificati (su FTP perché ampiamente supportati) fino al server di produzione

  3. Sul sito Web è presente un URL sicuro contenente un pulsante che copia tutto in "bin-pub" su "bin" (eseguendo prima un backup per abilitare il rollback rapido). A questo punto l'app si riavvia da sola. Quindi il nostro ORM verifica se ci sono tabelle o colonne da aggiungere e le crea.

Sono solo millisecondi di downtime. Il riavvio dell'app può richiedere uno o due secondi, ma durante il riavvio le richieste vengono memorizzate nel buffer in modo da ridurre effettivamente i tempi di inattività.

L'intero processo di distribuzione richiede da 5 secondi a 30 minuti, a seconda del numero di file modificati e di quanti cambiamenti riesaminare.

In questo modo non è necessario copiare un intero sito Web in una directory diversa ma solo la cartella bin. Hai anche il controllo completo sul processo e sai esattamente cosa sta cambiando.

** Facciamo sempre una rapida occhiata alle modifiche che stiamo implementando - come doppio controllo dell'ultimo minuto, quindi sappiamo cosa testare e se qualcosa si rompe siamo pronti. Usiamo Beyond Compare perché ti consente di diffondere facilmente i file tramite FTP. Non lo farei mai senza BC, non hai idea di cosa stai sovrascrivendo.

* Scorri verso il basso per vederlo :( A proposito, non consiglierei più i siti Web perché sono più lenti da costruire e possono arrestarsi in modo anomalo con file temporanei a metà compilati. Li abbiamo usati in passato perché consentivano file più agili- distribuzione per file. Molto veloce per risolvere un problema minore e puoi vedere esattamente cosa stai distribuendo (se usi Beyond Compare ovviamente - altrimenti dimenticalo).

I soli zero tempi di inattività che mi viene in mente di coinvolgere l'hosting su almeno 2 server.

Perfezionerei un po 'la risposta di George, come segue, per un singolo server:

  1. Utilizzare un progetto di distribuzione Web per precompilare il sito in una singola DLL
  2. Comprimi il nuovo sito e caricalo sul server
  3. Decomprimilo in una nuova cartella situata in una cartella con le giuste autorizzazioni per il sito, quindi i file decompressi ereditano correttamente le autorizzazioni (forse e: \ web, con le sottocartelle v20090901, v20090916, ecc)
  4. Utilizzare Gestione IIS per modificare il nome della cartella contenente il sito
  5. Conserva la vecchia cartella per un po ', in modo da poterla ricorrere in caso di problemi

Il passaggio 4 farà riciclare il processo di lavoro IIS.

Questo è solo zero tempi di inattività se non si utilizzano le sessioni InProc; usa invece la modalità SQL se puoi (ancora meglio, evita del tutto lo stato della sessione).

Naturalmente, è un po 'più coinvolto quando ci sono più server e / o modifiche al database ....

Per espandere la risposta di sklivvz, che si basava sull'avere un qualche tipo di bilanciamento del carico (o solo una copia in standby sullo stesso server)

  1. Indirizza tutto il traffico verso Site / Server 2
  2. Opzionalmente attendere un po ', per assicurarsi che il minor numero possibile di utenti abbia flussi di lavoro in sospeso sulla versione distribuita
  3. Distribuisci su Sito / Server 1 e riscaldalo il più possibile
  4. Esegui le migrazioni del database in modo transazionale (sforzati di renderlo possibile)
  5. Indirizza immediatamente tutto il traffico verso il sito / server 1
  6. Distribuisci su sito / server 2
  7. Indirizza il traffico verso entrambi i siti / server

È possibile introdurre un po 'di test del fumo, creando uno snapshot / copia del database, ma non è sempre possibile.

Se possibile e necessario, utilizzare le "differenze di routing", come ad esempio diversi URL degli inquilini: s (customerX.myapp.net) o utenti diversi, da distribuire prima a un gruppo inconsapevole di cavie. Se nulla fallisce, rilascialo a tutti.

Poiché sono coinvolte le migrazioni del database, è spesso impossibile tornare a una versione precedente.

Esistono modi per rendere le applicazioni più piacevoli in questi scenari, come l'utilizzo di code di eventi e meccanismi di riproduzione, ma dal momento che stiamo parlando di implementare le modifiche a qualcosa che è in uso, non c'è davvero alcun modo infallibile.

Ecco come lo faccio:

Requisiti minimi di sistema assoluti:
 1 server con

  • 1 bilanciamento del carico / proxy inverso (ad esempio nginx) in esecuzione sulla porta 80
  • 2 ASP.NET-Core / mono reverse-proxy / fastcgi chroot-jail o docker-container in ascolto su 2 diverse porte TCP
     (o anche solo due applicazioni proxy inverse su 2 porte TCP diverse senza sandbox)

Flusso di lavoro:

avvia transazione 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 

Suggerirei di conservare lì i vecchi file e semplicemente di sovrascriverli. In questo modo il tempo di inattività è limitato ai tempi di sovrascrittura a file singolo e manca sempre un solo file alla volta.

Non sono sicuro che ciò aiuti in un'applicazione web " sebbene (penso che tu stia dicendo che è quello che stai usando), motivo per cui usiamo sempre " siti web " ;. Anche con " siti web " la distribuzione non riavvia il sito e elimina tutte le sessioni utente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top