Aktualisieren Sie die .NET-Website ohne erneutes Laden

13

Früher habe ich Websites in PHPund entwickelt, ASP classicund 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 erstellt. C# MVCWenn Sie Änderungen am Code vornehmen, müssen Sie Ihre Website neu DLLerstellen und die geänderten Dateien hochladen . Wenn Sie jedoch Ihre DLLDateien ändern , wird Ihre Website neu gestartet und alle aktiven zurückgesetzt sessions. 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äßig "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 sind ähnlich und können mit einem Modul verarbeitet werden, das die richtigen Informationen basierend auf den Einstellungen anzeigt. Oft wird jedoch ein benutzerdefinierter Code benötigt.

Ich dachte an ein System, bei dem jede Promotion eine eigene DLLDatei ist, die auf einer Schnittstelle basiert, und die dann DLLdynamisch mit und geladen Type.GetTypewird . Obwohl das funktionieren könnte, frage ich mich, ob es der richtige Weg ist.Activator.CreateInstanceInvokeMember

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

Hugo Delsing
quelle
Als Antwort auf Ihren Kopfgeldkommentar: Die großen Websites, an denen ich arbeite, behandeln kleine Änderungen am Code genauso wie große Änderungen am Code: über Load-Balancer und Out-of-Process-Sitzungen - weil der gesamte Code, der für das Leben bereitgestellt wird, durchlaufen werden muss ein Überprüfungs- / Abmeldeprozess und wir können nicht einfach Code auf den Servern ablegen. Ich denke, unsere Definitionen von "groß" stimmen möglicherweise nicht überein;)
Zhaph - Ben Duguid

Antworten:

11

Lesen Sie "Anwendungsinitialisierung" in IIS 7.5, Windows 2008 R2 (schwieriger zu installieren), 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 wissen, was einen Neustart der Site auslöst. Da beim Neustart der Site nicht die Anwendungsinitialisierung verwendet wird, ist der Neustart der Site nicht nahtlos.

Sie können IIS so konfigurieren, dass ein DLL-Update nicht sofort einen Neustart der Site auslöst oder Änderungen an web.config (hohe ChangeNotification-Werte in der httpRuntime-Datei und in externen Konfigurationsdateien, die für Ihre Site relevant sind).

Das Endergebnis ist, dass Sie die DLLs / den Code ohne Neustart der Site aktualisieren und dann einen Neustart der App erzwingen können , bei dem das Aufwärmen des AppInitialization-Hintergrunds für die nahtlose Änderung des Codes verwendet wird.

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

Jeffreypriebe
quelle
Eine gute Reihe von Schritten - sicherlich etwas zu beachten :)
Zhaph - Ben Duguid
Das hört sich nach dem an, wonach ich gesucht habe. Probieren Sie es aus und richten Sie es ein. Vielen Dank
Hugo Delsing
@ HugoDelsing Hoffe, es funktioniert gut für Sie.
Jeffreypriebe
Danke, das habe ich letztendlich benutzt und es funktioniert großartig.
Hugo Delsing
Ich bin froh zu hören, dass es auch bei Ihnen funktioniert hat.
Jeffreypriebe
5

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

Behandeln Sie kleine Updates für Werbeaktionen

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 /bin/und /app_code/Ordner) berühren - und ein konfigurierbares Limit für "andere Dateiänderungen" hat (im Grunde genommen, wenn Sie dies geändert haben) Bei vielen Dateien auf Ihrer Site wird der Anwendungspool neu gestartet. - NumRecompilesBeforeAppRestart) Sie könnten versuchen, einen anderen Ordner nach statischen (dh .html) Dateien zu durchsuchen, die Sie nach Bedarf abrufen und anzeigen, oder die LoadControlMethode verwenden, die einen Zeichenfolgenpfad verwendet ein .ascxBenutzersteuerelement und lädt es dynamisch - wie Sie bestimmen, welches angezeigt werden soll, 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) verwenden, das seit Version 4 Bestandteil des .NET-Frameworks ist und es Ihnen ermöglicht, eine Plug-in-basierte Architektur zu schreiben und einen Ordner außerhalb Ihres /bin/Verzeichnisses anzugeben, auf den überwacht werden soll neue .DLLs - obwohl ich nicht versucht habe, das Problem mit dem Neustart der App zu vermeiden, habe ich dies in einer Webumgebung mit gutem Erfolg genutzt, um einer Site allgemeine Funktionen hinzuzufügen.

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 in klassischem ASP getan haben - dh mit einem <script runat="server">Block anstelle einer kompilierten "Code-behind" -Klasse Das Steuerelement enthält die Logik zum Ausführen des Steuerelements. Dadurch wird die Notwendigkeit einer DLL-Änderung auf Kosten eines erstmaligen Leistungsverlusts beseitigt, da das Steuerelement im laufenden Betrieb kompiliert wird. Sie müssen dies wiederum mit NumRecompilesBeforeAppRestartif you abwägen mache viele kleine Änderungen.

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 jedoch weiterhin für 8) als konstanten Wert, anstatt AutoGenerate- dies bedeutet, dass der AppPool beim Recyceln denselben Schlüssel verwendet und daher Sitzungscookies, ViewState usw. von früher entschlüsseln kann das recyceln.
  2. Richten Sie entweder einen Statusserver ein oder konfigurieren Sie eine Datenbank für den Sitzungsstatus .
  3. Wechseln Sie von der Verwendung InProczu StateServeroder SQLServerin das SessionState-Element in Ihrer web.config.

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 der Neustart der Anwendung nach einer Bereitstellung einige Minuten in Anspruch nimmt, sollten Sie in Betracht ziehen, auf eine Umgebung mit Lastenausgleich oder zumindest eine Hot-Swap-fähige Staging / Live-Einrichtung zu wechseln (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.

Zhaph - Ben Duguid
quelle
Vielen Dank für Ihre lange Antwort. Leider CMSnicht was ich will. Ich möchte den Inhalt nicht ändern, ich möchte den Code ändern. Der Teil über die Sitzungen war nur ein Beispiel. Wenn Sie es ändern, wird das Problem, dass die Site ein oder zwei Minuten lang nicht verfügbar ist, beim Neuladen von DLLDateien nicht behoben . Der MEFTeil war interessant, ist aber eine Drittanbieterlösung für das System, an das ich gedacht habe. Also +1 für die Mühe, aber leider ist es nicht wirklich eine Antwort auf meine Frage.
Hugo Delsing
1
Ich habe meine Antwort aktualisiert, um auf einige dieser Punkte einzugehen: MEF wurde von MS veröffentlicht und ist seit v4 ein vollständiger Bestandteil des .NET-Frameworks. Sie versuchen , Code-in-Front für die neuen Kontrollen verwenden , könnten alternativ einen Lastausgleich / staging-Live - Setup übernehmen , die einen Server und läuft bekommen würden ermöglichen, und tauschen sie dann in.
Zhaph - Ben Duguid
1
Ich habe eine alternative Lösung für die Anwendungsinitialisierung vorgestellt. Der Vorteil ist, dass das gesamte Code- und Server-Setup "normal" ist, ohne dass spezielle Steuerelemente für den Lastenausgleich oder das dynamische Laden erforderlich sind, wodurch Ihre Betriebsumgebung einfacher wird. Natürlich kann ein Load-Balancing / Staging-Live-Setup aus anderen Gründen hilfreich sein.
Jeffreypriebe