wake-up-neo.com

Aktualisieren Sie die .NET-Website, ohne sie neu zu laden

Ich habe Websites in PHP und ASP classic entwickelt und wenn etwas geändert werden musste. Sie könnten einfach eine oder mehrere Dateien ändern und niemand würde es wirklich bemerken. Vielleicht, wenn jemand die geänderte Datei während des Uploads anfordert, aber das entspricht einer halben Sekunde. Für die meisten kleineren Websites ist das kein Problem.

Die neuesten Websites werden jedoch mit C#MVC erstellt. Wenn Sie Änderungen am Code vornehmen, müssen Sie Ihre Website neu erstellen und die geänderten DLL -Dateien hochladen. Wenn Sie jedoch Ihre DLL Dateien ändern, wird Ihre Website neu gestartet und alle aktiven sessions zurückgesetzt. Es muss auch alles neu geladen werden und bei großen Websites kann es einige Minuten dauern, bis alles geladen ist. Jeder, der die Website besucht hat, wird es bemerken und muss sich erneut anmelden.

Wichtige Site-Updates sind nicht so häufig, das ist also kein Problem. Wir haben jedoch regelmäßige "kleine" Updates für Werbeaktionen. Wie "Füllen Sie dieses Formular aus und erhalten Sie drei Monate kostenlose Mitgliedschaft" oder "Die ersten 10, die ein Bild von ... hochladen, erhalten einen Preis". Ich denke, Sie werden den Drift bekommen. Einige Werbeaktionen ähneln sich und können mit einem Modul verarbeitet werden, das die richtigen Informationen basierend auf den Einstellungen anzeigt. Oft ist jedoch ein benutzerdefinierter Code erforderlich.

Ich dachte an ein System, in dem jede Promotion eine eigene DLL Datei ist, die auf einer Schnittstelle basiert, und lade dann die DLL dynamisch mit Type.GetType, Activator.CreateInstance und InvokeMember. Obwohl das funktionieren könnte, frage ich mich, ob es der richtige Weg ist.

Also meine Frage: Wie aktualisiere ich eine .NET Site im laufenden Betrieb, ohne die gesamte Site neu zu laden und die Sitzung zu löschen (wie zum Beispiel den Anwendungspool zu recyceln)?.

13
Hugo Delsing

Lesen Sie "Anwendungsinitialisierung" IIS 7.5, Windows 2008 R2 (schwerer einzurichten) IIS 8, Windows 2012

Durch die App-Initialisierung kann sich jeder Neustart einer Anwendung (Anwendungspool nicht Standort) überlappen und die alte verwenden. Die vorherige Anwendung wird weiterhin ausgeführt, während der Start der neuen Anwendung aufgewärmt wird. Sobald die neue Anwendung hochgefahren ist (bestimmt durch die URLs, die Sie festlegen können), verwendet sie die neue Anwendung und fährt die vorherige herunter. Wenn Sie die App-Initialisierung in Verbindung mit Methoden verwenden, um sicherzustellen, dass die Sitzung über Anwendungspool-Neustarts hinweg bestehen bleibt, kann Ihre Site nahtlos neu gestartet werden. (Zhaph hat eine gute Notiz über den Maschinenschlüssel.)

Zusätzlich zu den obigen Links für die Konfiguration der App-Initialisierung möchten Sie sehen, was einen Neustart der Site auslöst - da beim Neustart der Site nicht die Application Initiliazation the verwendet wird Der Neustart der Site verläuft nicht nahtlos.

Sie können IIS so konfigurieren, dass ein DLL Update weder einen sofortigen Neustart der Site auslöst noch Änderungen an web.config (hohe ChangeNotification-Werte in den httpRuntime- und externen Konfigurationsdateien, sofern relevant) vornimmt zu Ihrer Site).

Das Endergebnis ist, dass Sie die DLLs/den Code ohne Neustart der Site aktualisieren und dann einen App-Neustart erzwingen können, der das AppInitialization-Hintergrund-Warm-up für die nahtlose Änderung des Codes verwendet.

Wenn Sie diese Dinge im Konzert tun, ist dies für einen nahtlosen Neustart recht gut.

11
jeffreypriebe

Es gibt verschiedene Möglichkeiten, mit Ihren Fragen umzugehen, und einige unterschiedliche Aspekte Ihrer Frage:

Kleine Updates für Werbeaktionen verarbeiten

Was Sie hier wirklich suchen, ist ein Content-Management-System oder ähnliches, mit dem Sie den Inhalt im Handumdrehen bearbeiten können (beispielsweise Wordpress/Drupal oder aus .NET-Sicht N2 CMS, Umbraco, Orchard usw.) Es gibt einige Dinge, die Sie ausprobieren könnten, wenn Sie diesen Weg nicht gegangen sind.

Da ASP.NET nur dann wirklich neu geladen wird, wenn Sie bestimmte Dateitypen (web.config (s), hauptsächlich den Inhalt der Ordner /bin/ und /app_code/) berühren - und ein konfigurierbares Limit für "andere Dateiänderungen" hat (im Grunde genommen, sobald Sie dies getan haben) Wenn Sie so viele Dateien in Ihrer Site geändert haben, dass der Anwendungspool neu gestartet wird - NumRecompilesBeforeAppRestart ) könnten Sie versuchen, einen anderen Ordner auf statische (dh .html) Dateien zu überprüfen, die Sie nach Bedarf abrufen und anzeigen Oder verwenden Sie die LoadControl-Methode, die einen Zeichenfolgenpfad zu einem .ascx-Benutzersteuerelement nimmt und dieses dynamisch lädt - wie Sie bestimmen, welches angezeigt wird, ist eine andere Frage, die besser für StackOverflow geeignet ist. Ich würde jedoch eine auf Namenskonventionen basierende Lösung empfehlen.

Sie können auch das Managed Extensibility Framework (MEF - das seit Version 4 Bestandteil des .NET-Frameworks ist) verwenden, mit dem Sie eine Plug-in-basierte Architektur schreiben und einen Ordner angeben können Außerhalb Ihres /bin/ -Verzeichnisses, um nach neuen .DLLs zu suchen - obwohl ich nicht versucht habe, dies zu überprüfen, um das Problem des App-Neustarts zu vermeiden, habe ich dies in einer Webumgebung zum Hinzufügen allgemeiner Funktionen zu einer Site verwendet.

Wenn das nicht gefällt, ist die einzige andere Option, die ich mir vorstellen kann, die Steuerelemente als "Code-in-Front" hinzuzufügen, wie wir es im klassischen ASP getan haben - dh mit einem <script runat="server">-Block anstelle eines Kompilierte "CodeBehind" -Klasse, die die Logik zum Ausführen des Steuerelements enthält. Dadurch wird die Notwendigkeit einer DLL -Änderung auf Kosten eines erstmaligen Leistungsverlusts beseitigt, da das Steuerelement im laufenden Betrieb kompiliert wird - Auch dies müssen Sie mit NumRecompilesBeforeAppRestart abwägen, wenn Sie viele kleine Änderungen vornehmen.

Wie kann ich Sitzungen über App-Neustarts hinweg beibehalten?

Dies ist möglicherweise einfacher zu lösen und umfasst drei wichtige Schritte:

  1. Konfigurieren Sie den MachineKey (IIS7, gilt aber weiterhin für 8) als konstanten Wert und nicht als AutoGenerate - dies bedeutet, dass der AppPool beim Recycling denselben Schlüssel verwendet und die Sitzung entschlüsseln kann Cookies, Viewstate, etc. von vor dem Recycling.
  2. Entweder einen Statusserver einrichten oder eine Datenbank so konfigurieren, dass sie den Sitzungsstatus enthält .
  3. Wechseln Sie im SessionState-Element in Ihrer web.config von InProc zu StateServer oder SQLServer.

Auf diese Weise haben Sie dauerhafte Sitzungen, die einen Neustart der App überstehen. Diese sind jedoch nicht "kostenlos" - alles, was Sie in der Sitzung speichern, muss jetzt serialisierbar sein, und Sie werden einen leichten Leistungseinbruch erleiden, da für das Laden jeder Seite zusätzliche Netzwerk-Trips erforderlich sind, um die Sitzungsdaten abzurufen und möglicherweise freizugeben.

Wenn Sie sich jedoch in einer Situation befinden, in der es "einige Minuten" dauert, bis die Anwendung nach einer Bereitstellung neu gestartet wird, sollten Sie in Betracht ziehen, auf eine Umgebung mit Lastenausgleich oder zumindest eine Hot-Swap-fähige Staging/Live-Einrichtung umzusteigen (wie das von Azure/AWS/etc. bereitgestellte) - Auf diese Weise können Sie einen Server offline schalten, während Sie ihn aktualisieren, oder ihn mit dem neuen Code vorbereiten und dann austauschen - vorausgesetzt, Sie haben die Schritte zur Adressfreigabe ausgeführt Sitzungen (siehe oben) Dies funktioniert einwandfrei und hat keine Auswirkungen auf Ihre Benutzer.

5