Freigeben über


Beseitigen Sie Ausfallzeiten durch versionierte Dienst-Updates

In der Vergangenheit mussten Administratoren einen Server offline schalten, um On-Premises-Software zu aktualisieren und zu upgraden. Ausfallzeiten sind jedoch absolut inakzeptabel für globale Dienste im 24×7-Betrieb. Viele moderne Clouddienste sind eine wichtige Abhängigkeit für Benutzer, um ihre Unternehmen zu führen. Es gibt nie eine gute Zeit, ein System herunterzunehmen, also wie kann ein Team einen kontinuierlichen Dienst bereitstellen, während wichtige Sicherheits- und Featureupdates installiert werden?

Durch die Verwendung versionsgesteuerter Updates können diese kritischen Dienste nahtlos von einer Version zu einer anderen übertragen werden , während Kunden sie aktiv nutzen. Nicht alle Updates sind schwierig. Das Aktualisieren von Front-End-Layouts oder Formatvorlagen ist einfach. Änderungen an Features können schwierig sein, aber es gibt bekannte Methoden, um Migrationsrisiken zu minimieren. Änderungen, die von der Datenebene ausgehen, führen jedoch zu einer neuen Herausforderungsklasse, die besondere Berücksichtigung erfordern.

Ebenen separat aktualisieren

Mit einem verteilten Onlinedienst in mehreren Rechenzentren und separatem Datenspeicher können sich nicht alles gleichzeitig ändern. Wenn der typische Dienst in Anwendungscode und Datenbanken aufgeteilt wird, die vermutlich unabhängig voneinander versioniert sind, muss eine dieser Seiten die Komplexität der Versionsverwaltung aufnehmen.

Häufig ist die Versionsverwaltung im Anwendungscode einfacher zu behandeln. Größere Systeme verfügen in der Regel über ein wenig Legacycode, z. B. SQL, das sich in seinen Datenbanken befindet. Anstatt diese SQL weiter zu komplizieren, sollte der Anwendungscode die Komplexität behandeln. Insbesondere können Sie eine Reihe von Factoryklassen erstellen, die die SQL-Versionsverwaltung verstehen.

Erstellen Sie während jedes Sprints eine neue Schnittstelle mit dieser Version, sodass immer Code vorhanden ist, der jeder Datenbankversion entspricht. Sie können alle Binärdateien während der Bereitstellung problemlos zurücksetzen. Wenn nach der Bereitstellung der neuen Binärdateien ein Fehler auftritt, stellen Sie den vorherigen Code wieder her. Wenn die binäre Bereitstellung erfolgreich ist, starten Sie die Datenbankwartung.

Wie funktioniert das eigentlich? Angenommen, Ihr Team stellt derzeit Sprint 123 bereit. Die Binärdateien verstehen das Sprint 123-Datenbankschema und verstehen das Sprint 122-Schema. Das allgemeine Muster besteht darin, mit beiden Versionen/Sprints N und N-1 des SQL-Schemas zu arbeiten. Die Binärdateien fragen die Datenbank ab, ermitteln, welche Schemaversion verwendet wird, und laden dann die entsprechende Bindung. Anschließend behandelt der Anwendungscode den Fall, wenn das neue Datenschema noch nicht verfügbar ist. Sobald die neue Version verfügbar ist, kann der Anwendungscode mit der Verwendung der neuen Funktionalität beginnen, die von der neuesten Datenbankversion aktiviert ist.

Nur mit der Datenebene vorwärts ausführen

Nachdem Datenbanken aktualisiert wurden, befindet sich der Dienst in einer Roll-Forward-Situation , wenn ein Problem auftritt. Onlinedatenbankmigrationen sind komplex und beinhalten häufig mehrere Schritte, weshalb das Weiterrollen in der Regel die beste Möglichkeit ist, ein Problem zu beheben. Anders ausgedrückt: Wenn das Upgrade fehlschlägt, schlägt das Rollback wahrscheinlich ebenfalls fehl. Es lohnt sich kaum, die Mühe in das Erstellen und Testen von Rollback-Code zu investieren, den Ihr Team niemals nutzen möchte.

Reihenfolge des Einsatzes

Betrachten Sie ein Szenario, in dem Sie einer Datenbank eine Reihe von Spalten hinzufügen und einige Daten transformieren müssen. Dieser Übergang muss für Benutzer unsichtbar sein, was bedeutet, dass Tabellensperren möglichst vermieden und dann Sperren für die kürzeste Zeit aufbewahrt werden, damit sie nicht bemerkbar sind.

Als Erstes bearbeiten wir die Daten, möglicherweise in parallelen Tabellen, mithilfe eines SQL-Triggers, um Daten synchron zu halten. Große Datenmigrationen und Transformationen müssen manchmal mehrere Bereitstellungen in mehreren Sprints durchlaufen.

Sobald die zusätzlichen Daten oder das neue Schema parallel erstellt wurden, wechselt das Team in den Bereitstellungsmodus für den Anwendungscode. Wenn der Code im Bereitstellungsmodus einen Aufruf der Datenbank ausführt, greift er zuerst eine Sperre für das Schema ab und gibt sie nach dem Ausführen der gespeicherten Prozedur los. Die Datenbank kann sich nicht zwischen dem Zeitpunkt ändern, an dem der Aufruf der Datenbank ausgegeben wird und wann die gespeicherte Prozedur ausgeführt wird.

Der Upgrade-Code fungiert als Schema-Writer und fordert eine Writer-Sperre für das Schema an. Der Anwendungscode hat Vorrang bei der Verwendung einer Lesesperre, und der Upgradecode befindet sich im Hintergrund, um die Writer-Sperre zu erwerben. Unter dem Writer-Lock sind nur wenige sehr schnelle Operationen auf den Tabellen zulässig. Anschließend wird die Sperre freigegeben, und die Anwendung zeichnet die neue Version der Datenbank auf und verwendet die Schnittstelle, die der neuen Datenbankversion entspricht.

Die Datenbankupgrades werden alle mithilfe eines Migrationsmusters ausgeführt. Eine Reihe von Code und Skripts untersuchen die Version der Datenbank und nehmen dann inkrementelle Änderungen vor, um das Schema von der alten zur neuen Version zu migrieren. Alle Migrationen werden automatisiert und über den Releaseverwaltungsdienst bereitgestellt.

Die Web-UI muss auch aktualisiert werden, ohne die Benutzer zu stören. Vermeiden Sie beim Aktualisieren von JavaScript-Dateien, Stylesheets oder Bildern das Mischen alter und neuer Versionen, die vom Client geladen werden. Dies kann zu Fehlern führen, die den Fortschritt der Arbeit gefährden könnten, wie beispielsweise bei einem Feld, das gerade von einem Benutzer bearbeitet wird. Daher sollten Sie alle JavaScript-, CSS- und Bilddateien versionieren, indem Sie alle Dateien, die einer Bereitstellung zugeordnet sind, in einen separaten, versionsbezogenen Ordner einfügen. Wenn die Webbenutzeroberfläche Aufrufe an die Anwendungsebene sendet, werden Ressourcen mit einer angegebenen Version geladen. Nur wenn eine Benutzeraktion zu einer Vollständigen Seitenaktualisierung führt, wird die neue Webbenutzeroberfläche in den Browser geladen. Die Benutzererfahrung wird durch das Upgrade nicht gestört.

Nächste Schritte

Microsoft ist seit Jahrzehnten einer der weltweit größten Softwareentwicklungsunternehmen. Erfahren Sie, wie Microsoft zuverlässige Systeme mit DevOps betreibt.