Aggiorna il sito Web .NET senza ricaricare


13

Ho usato per sviluppare siti web di PHPe ASP classice se qualcosa doveva essere cambiato. Potresti semplicemente modificare un singolo / più file e nessuno se ne accorgerebbe davvero. Forse se qualcuno richiederebbe il file modificato durante il caricamento, ma è come mezzo secondo margine. Per la maggior parte dei siti più piccoli non è un problema.

Ma vengono creati gli ultimi siti C# MVCe quando si apportano modifiche al codice, è necessario ricostruire il sito Web e caricare i DLLfile modificati . Ma quando modifichi i tuoi DLLfile, riavvierai il tuo sito Web e ripristinerai tutti gli attivi sessions. Deve anche ricaricare tutto e con siti di grandi dimensioni possono essere necessari alcuni minuti per caricare tutto. Chiunque stia navigando sul sito noterà e dovrà accedere di nuovo.

I principali aggiornamenti del sito non sono così comuni, quindi non è un problema. Ma abbiamo regolari "piccoli" aggiornamenti per le promozioni. Ad esempio "Compila questo modulo e ottieni tre mesi di abbonamento gratuito" o "I primi 10 per caricare un'immagine di ... riceveranno un prezzo". Penso che otterrai la deriva. Alcune promozioni sono simili e potrebbero essere gestite con un modulo che mostra le informazioni giuste in base alle impostazioni, ma molto spesso richiede un codice personalizzato.

Stavo pensando a un sistema in cui ogni promozione è il proprio DLLfile basato su un'interfaccia, quindi caricare DLLdinamicamente usando Type.GetType, Activator.CreateInstancee InvokeMember. Anche se potrebbe funzionare, mi chiedo se sia la strada giusta da percorrere.

Quindi la mia domanda: come si aggiorna un .NETsito al volo, senza ricaricare l'intero sito e abbandonare la sessione (come riciclare il pool di applicazioni).


In risposta al tuo commento generoso: i siti Web di grandi dimensioni su cui lavoro gestiscono piccole modifiche al codice nello stesso modo in cui gestiscono grandi modifiche al codice: tramite bilanciamento del carico e sessioni fuori processo - perché tutto il codice che viene distribuito per vivere deve passare attraverso un processo di revisione / approvazione e non possiamo semplicemente rilasciare il codice sui server. Suppongo che le nostre definizioni di "grande" potrebbero non corrispondere;)
Zhaph - Ben Duguid,

Risposte:


11

Cerca in "Inizializzazione dell'applicazione" IIS 7.5, Windows 2008 R2 (più difficile da installare) IIS 8, Windows 2012

L'inizializzazione dell'app consente a qualsiasi applicazione (pool di applicazioni non sito) di sovrapporsi e utilizzare la vecchia, eseguendo comunque l'applicazione precedente durante il riscaldamento dell'avvio della nuova applicazione. Una volta avviata la nuova applicazione (determinata dagli URL che è possibile impostare), inizierà a utilizzare la nuova applicazione e chiuderà quella precedente. L'uso dell'inizializzazione delle app insieme ai metodi per garantire che la sessione rimanga tra i riavvii del pool di applicazioni può consentire il riavvio senza interruzioni del sito. (Zhaph ha una buona nota sulla chiave della macchina.)

Oltre ai collegamenti di cui sopra per la configurazione di inizializzazione dell'app, ti consigliamo di vedere cosa innesca un riavvio del sito - poiché il riavvio del sito non utilizza l' inizializzazione dell'applicazione, il riavvio del sito non sarà senza interruzioni.

È possibile configurare IIS in modo che un aggiornamento DLL non attivi immediatamente un riavvio del sito, né cambi in web.config (elevati valori di ChangeNotification sui file httpRuntime e di configurazione esterni, come rilevanti per il proprio sito).

Il risultato finale è che è possibile aggiornare le DLL / il codice senza riavviare il sito, quindi forzare un riavvio dell'app che utilizzerà il riscaldamento in background di AppInitialization per il cambio continuo di codice.

Fare queste cose in concerto funziona abbastanza bene per riavvii senza soluzione di continuità.


Una buona serie di passaggi lì - sicuramente qualcosa da considerare :)
Zhaph - Ben Duguid,

Sembra quello che stavo cercando. Provando e configurandolo. Grazie
Hugo Delsing,

@HugoDelsing Spero che funzioni alla grande per te.
jeffreypriebe,

Grazie, questo è quello che ho finito per usare e funziona benissimo.
Hugo Delsing,

@HugoDelsing Sono contento di sentire che ha funzionato anche per te.
jeffreypriebe,

5

Esistono diversi modi per gestire ciò che stai chiedendo e alcuni aspetti diversi della tua domanda:

Gestisci piccoli aggiornamenti per le promozioni

Quello che stai veramente cercando qui è un sistema di gestione dei contenuti o simile che ti permetta di modificare il contenuto al volo (pensa Wordpress / Drupal o da un punto di vista .NET N2 CMS, Umbraco, Orchard, ecc.), Tuttavia lì sono alcune cose che potresti provare se non hai seguito quella strada.

Perché ASP.NET si ricarica davvero solo se si toccano determinati tipi di file (web.config (s), principalmente il contenuto delle cartelle /bin/e /app_code/) - e ha un limite configurabile per "altre modifiche ai file" (in pratica una volta modificato molti file all'interno del tuo sito verranno riavviati dal pool di applicazioni - NumRecompilesBeforeAppRestart) potresti provare a fare qualcosa in cui controlli una cartella diversa per alcuni file statici (ad es. .html) che tiri dentro e visualizzi come necessario, o usi il LoadControlmetodo che prende un percorso di stringa a un .ascxcontrollo utente e lo carica in modo dinamico - come determinare quale mostrare è una domanda diversa più adatta a StackOverflow - tuttavia consiglierei una soluzione basata sulla convenzione di denominazione.

Puoi anche cercare di utilizzare qualcosa come Managed Extensibility Framework (MEF - che è parte integrante del framework .NET dalla versione 4) che ti consente di scrivere un'architettura basata su plug-in e specificare una cartella esterna /bin/alla directory per cui monitorare nuovi .DLL - anche se non ho provato questo per vedere se eviterà il problema di riavvio dell'app, l'ho usato con buoni risultati in un ambiente web per aggiungere funzionalità comuni a un sito.

Se ciò non fa appello, l'unica altra opzione a cui riesco a pensare sarebbe quella di aggiungere i controlli come "code-in-front" come facevamo nel classico ASP - cioè con un <script runat="server">blocco anziché una classe "code-behind" compilata che contiene la logica per eseguire il controllo - questo rimuoverà la necessità di una modifica della DLL, a scapito di una perdita di prestazioni per la prima volta quando il controllo viene compilato al volo - di nuovo dovrai bilanciarlo con il NumRecompilesBeforeAppRestartse tu stai facendo molti piccoli cambiamenti.

Come persisto sessioni tra i riavvi delle app?

Questo è probabilmente un problema più semplice da risolvere e prevede tre passaggi chiave:

  1. Configura MachineKey (IIS7, ma vale ancora per 8) in modo che sia un valore costante anziché AutoGenerate- ciò significa che quando AppPool ricicla utilizzerà la stessa chiave e sarà quindi in grado di decrittografare i cookie di sessione, viewstate, ecc. Da prima il riciclo.
  2. O impostare un server di stato o di configurare un database per tenere stato sessione .
  3. Passa dall'uso InProca StateServero SQLServernell'elemento SessionState nel tuo web.config.

In questo modo avrai sessioni persistenti che sopravvivranno al riavvio dell'app. Tuttavia, questi non sono "gratuiti": tutto ciò che memorizzi nella sessione ora deve essere serializzabile e subirai un leggero calo delle prestazioni poiché ogni caricamento della pagina richiederà ora ulteriori viaggi di rete per ottenere e potenzialmente rilasciare i dati della sessione.

Tuttavia, se ti trovi in ​​una posizione in cui sono necessari "diversi minuti" per il riavvio dell'applicazione dopo una distribuzione, ti consigliamo di passare a un ambiente con bilanciamento del carico o almeno a una configurazione di gestione temporanea / live sostituibile a caldo (come quello fornito da Azure / AWS / ecc.) - in questo modo puoi portare un server offline mentre lo aggiorni o lo prepari con il nuovo codice e poi lo cambi - a condizione che tu abbia preso le misure per affrontare la condivisione sessioni (vedi sopra) funzionerà bene senza alcun impatto per i tuoi utenti.


Grazie per la tua lunga risposta. Purtroppo CMSnon è quello che voglio. Non voglio modificare il contenuto, voglio modificare il codice. La parte relativa alle sessioni era solo un esempio. Modificarlo non risolverà il problema del sito inattivo per un minuto o due durante il ricaricamento dei DLLfile. La MEFparte è stata interessante, ma è una soluzione di terze parti al sistema a cui stavo pensando. Quindi +1 per lo sforzo, ma sfortunatamente non è proprio una risposta alla mia domanda.
Hugo Delsing,

1
Ho aggiornato la mia risposta per affrontare un paio di questi punti: MEF è stato rilasciato da MS ed è parte integrante del framework .NET dalla v4. Potresti provare a utilizzare il code-in-front per i tuoi nuovi controlli, in alternativa adottare una configurazione con bilanciamento del carico / staging-live che consentirebbe di avviare e far funzionare un server e poi scambiarlo.
Zhaph - Ben Duguid,

1
Ho delineato una soluzione alternativa utilizzando l'inizializzazione dell'applicazione. Il vantaggio è che tutto il codice e la configurazione del server sono "normali" senza speciali bilanciamento del carico o caricamento dinamico dei controlli, semplificando l'ambiente di corsa. Naturalmente, un'impostazione di bilanciamento del carico / staging-live potrebbe essere utile per altri motivi.
jeffreypriebe,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.