Eliminieren Sie Ausfallzeiten durch versionierte Service-Updates

In der Vergangenheit mussten Administratoren einen Server offline schalten, um Software vor Ort zu aktualisieren und aufzurüsten. Für globale 24×7-Dienste sind Ausfallzeiten jedoch ein absolutes No-Go. Viele moderne Cloud-Dienste sind für die Nutzer eine wichtige Voraussetzung für den Betrieb ihrer Unternehmen. Es gibt nie einen guten Zeitpunkt, um ein System herunterzufahren. Wie also kann ein Team kontinuierlichen Service bieten und gleichzeitig wichtige Sicherheits- und Funktionsupdates installieren?

Durch die Verwendung von versionierten Updates können diese kritischen Dienste nahtlos von einer Version auf eine andere umgestellt werden , während die Kunden sie aktiv nutzen. Nicht alle Aktualisierungen sind schwierig. Die Aktualisierung von Front-End-Layouts oder Stilen ist einfach. Änderungen an Funktionen können schwierig sein, aber es gibt bekannte Praktiken, um die Migrationsrisiken zu minimieren. Änderungen, die von der Datenebene ausgehen, bringen jedoch eine neue Klasse von Herausforderungen mit sich, die besondere Aufmerksamkeit erfordern.

Ebenen separat aktualisieren

Bei einem verteilten Online-Dienst in mehreren Rechenzentren und getrennter Datenspeicherung kann sich nicht alles gleichzeitig ändern. Wenn der typische Dienst in Anwendungscode und Datenbanken aufgeteilt ist, die vermutlich unabhängig voneinander versioniert werden, muss eine der beiden Seiten die Komplexität der Versionsverwaltung übernehmen.

Oft ist die Versionierung im Anwendungscode einfacher zu handhaben. Größere Systeme verfügen in der Regel über eine ganze Reihe von Legacy-Code, z. B. SQL, der in den Datenbanken enthalten ist. Anstatt diese SQL weiter zu verkomplizieren, sollte der Anwendungscode die Komplexität bewältigen. Insbesondere können Sie eine Reihe von Fabrikklassen erstellen, die die SQL-Versionierung verstehen.

Erstellen Sie in jedem Sprint eine neue Schnittstelle mit dieser Version, damit es immer Code gibt, der zu jeder Datenbankversion passt. Sie können alle Binärdateien während der Bereitstellung problemlos zurücksetzen. Wenn nach der Bereitstellung der neuen Binärdateien etwas schief geht, kehren Sie zum vorherigen Code zurück. Wenn die Binärverteilung erfolgreich war, starten Sie die Datenbankwartung.

Und wie funktioniert das eigentlich? Nehmen wir zum Beispiel an, dass Ihr Team gerade Sprint 123 durchführt. Die Binärdateien verstehen das Sprint 123-Datenbankschema und sie verstehen das Sprint 122-Schema. Das allgemeine Muster ist, mit beiden Versionen/Sprints N und N-1 des SQL-Schemas zu arbeiten. Die Binärdateien fragen die Datenbank ab, stellen fest, mit welcher Schemaversion sie kommunizieren, und laden dann die entsprechende Bindung. Der Anwendungscode behandelt dann den Fall, dass das neue Datenschema noch nicht verfügbar ist. Sobald die neue Version verfügbar ist, kann der Anwendungscode die neuen Funktionen nutzen, die durch die neueste Datenbankversion ermöglicht werden.

Vorwärtsrollen nur mit der Datenschicht

Sobald die Datenbanken aktualisiert wurden, befindet sich der Dienst in einer Roll-Forward-Situation, wenn ein Problem auftritt. Online-Datenbankmigrationen sind komplex und erfolgen oft in mehreren Schritten, so dass ein „Rolling Forward“ in der Regel der beste Weg ist, ein Problem zu lösen. Mit anderen Worten: Wenn das Upgrade fehlschlägt, wird wahrscheinlich auch das Rollback fehlschlagen. Es ist wenig sinnvoll, in die Erstellung und das Testen von Rollback-Code zu investieren, den Ihr Team voraussichtlich nie verwenden wird.

Reihenfolge des Einsatzes

Stellen Sie sich ein Szenario vor, in dem Sie eine Reihe von Spalten zu einer Datenbank hinzufügen und einige Daten umwandeln müssen. Dieser Übergang muss für die Benutzer unsichtbar sein, was bedeutet, dass Tabellensperren so weit wie möglich vermieden und Sperren so kurz wie möglich gehalten werden, damit sie nicht wahrnehmbar sind.

Als Erstes werden die Daten bearbeitet, möglicherweise in parallelen Tabellen unter Verwendung eines SQL-Triggers, um die Daten synchron zu halten. Große Datenmigrationen und -transformationen müssen manchmal in mehreren Schritten über mehrere Sprints hinweg durchgeführt werden.

Sobald die zusätzlichen Daten oder das neue Schema parallel erstellt worden sind, geht das Team in den Bereitstellungsmodus für den Anwendungscode über. Wenn der Code im Bereitstellungsmodus die Datenbank aufruft, wird zunächst eine Sperre für das Schema aktiviert und nach Ausführung der gespeicherten Prozedur wieder freigegeben. Die Datenbank kann sich zwischen dem Aufruf der Datenbank und der Ausführung der gespeicherten Prozedur nicht mehr ändern.

Der Upgrade-Code fungiert als Schema-Schreiber und fordert eine Schreibsperre für das Schema an. Der Anwendungscode hat Vorrang, wenn es darum geht, eine Lesesperre zu erhalten, und der Aktualisierungscode sitzt im Hintergrund und versucht, die Schreibsperre zu erhalten. Unter der Schreibsperre ist nur eine kleine Anzahl von sehr schnellen Operationen auf den Tabellen erlaubt. Dann wird die Sperre aufgehoben und die Anwendung registriert, dass die neue Version der Datenbank verwendet wird, und verwendet die Schnittstelle, die der neuen Datenbankversion entspricht.

Die Datenbank-Upgrades werden alle nach einem Migrationsmuster durchgeführt. Ein Satz von Code und Skripten prüft die Version der Datenbank und nimmt dann schrittweise Änderungen vor, um das Schema von der alten auf die neue Version zu migrieren. Alle Migrationen werden automatisiert und über den Release Management Service ausgerollt.

Auch die Web-UI muss aktualisiert werden, ohne die Benutzer zu stören. Wenn Sie JavaScript-Dateien, Stylesheets oder Bilder aktualisieren, müssen Sie vermeiden, dass alte und neue Versionen vom Client geladen werden. Dies kann zu Fehlern führen, durch die laufende Arbeiten verloren gehen können, z. B. wenn ein Feld von einem Benutzer bearbeitet wird. Daher müssen Sie alle JavaScript-, CSS- und Bilddateien versionieren, indem Sie alle mit einer Bereitstellung verbundenen Dateien in einem separaten, versionierten Ordner ablegen. Wenn die Web-UI die Anwendungsschicht aufruft, werden Assets mit einer bestimmten Version geladen. Nur wenn eine Benutzeraktion zu einer vollständigen Aktualisierung der Seite führt, wird die neue Web-UI in den Browser geladen. Die Benutzererfahrung wird durch das Upgrade nicht beeinträchtigt.

Nächste Schritte

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