Implementierung ohne Ausfälle mit Magento Commerce
Magento Commerce wurde vor mehr als zweieinhalb Jahren veröffentlicht, und doch hat die Magento-Community noch keine Lösung für das Blue-Green Deployment - die automatisierte Deploymenttechnologie. In diesem Artikel untersuche ich eine Lösung für die Realisierung von Zero-Downtime Deployments mit Magento Commerce.
Die Vorteile des Blue-Green Deployments
Martin Fowler, eine anerkannte Autorität auf dem Gebiet des Designs von Unternehmenssoftware, gibt hier einen großen Überblick über die Vorteile von Blue-Green Deployments. Im Wesentlichen haben Sie zwei Produktionsumgebungen, die so identisch wie möglich sind. Zu jeder Zeit ist einer von ihnen live, und während Sie ein neues Release Ihrer Software vorbereiten, machen Sie Ihre letzte Testphase in der anderen Umgebung.
Die Grundidee ist, problemlos zwischen zwei Umgebungen wechseln zu können.
Martin Fowler
Hier bei Inviqa verwenden wir Blue-Green Deployments als Mechanismus für das Deployment von Releases über mehrere Nodes (oder Server) hinweg, bei denen wir das Entfernen alter Container und das Bereitstellen neuer Container zeitlich verschieben, ohne die Kundenzufriedenheit zu beeinträchtigen.
Wir können den Prozess besser verstehen, wenn wir das folgende Beispiel für ein einfaches Two-Node-Setup mit einer zentralisierten Datenbank betrachten:
- Erstellung eines neuen Docker-Image auf dem Build-Server
- Deployment eines neuen Containers zur 1. Node (und Ausführung aller nötigen Änderungen an der zentralisierten Datenbank)
- Entfernen des alten Containers aus der 1. Node
- Einsetzen des neuen Containers in die 2. Node
- Entfernen des alten Containers aus der 2. Node
- Deployment abgeschlossen
Es ist klar, dass es während eines Blue-Green Deployment Prozesses möglich ist, dass sowohl alte als auch neue Container HTTP-Requests empfangen können. Daher ist es wichtig, dass sowohl unser alter als auch unser neuer Code mit allen Datenbank-Schemaänderungen arbeitet, die während des Deployment-Prozesses angewendet werden.
Wir verwenden Blue-Green bei Inviqa, um Zero-Downtime-Implementierungen zu erreichen, die ein großes Problem mit Magento Commerce darstellten. In der Community gab es viele Gerüchte über das Eliminieren von Ausfallzeiten, aber konnte ist keines davon in die Tat umgesetzt werden.
Die Herausforderung automatisierter Deployments mit Magento Commerce
Um klarzustellen, was wir meinen, sollte ein Zero Downtime Deployment Modell die folgenden Kriterien erfüllen:
- Keine Wartungsseite
- Arbeitet mit containerbasierten Deployments (aber auch mit traditionellen Einzel- oder Multiserver-Deployments).
- Hat keine Auswirkungen auf den Benutzer (z.B. Checkout-Prozesse).
Es gab mehrere Versuche, dieses Problem zu lösen, aber keiner davon erfüllt die oben genannten Kriterien. Einige der Lösungen implementieren eine Wartungsseite. Einige mögen gut funktionieren, unterstützen aber keine containerbasierten Konfigurationen. Andere wiederum halten 20 Sekunden Ausfallzeit für akzeptabel, aber beim Umgang mit E-Commerce muss „Zero Downtime“ im wortwörtlichen Sinn, also absolute Ausfallfreiheit, angestrebt werden.
Die größte Schwierigkeit bei Magento's Deployment-Prozess ist der Mechanismus, in dem es Datenbankänderungen während der Deployment anwendet: der Befehl setup:upgrade. Dies wird als Teil eines jeden Deployments ausgeführt und wendet Daten- und Schemaänderungen auf die Zieldatenbank für Module an, bei denen die Modulversion des Anwendungscodes hinter der Gegenstückversion der Datenbank liegt.
Wenn eine Anfrage von Magento empfangen wird, überprüft es die Modulversionen auf der Festplatte mit denen in der Datenbank und gibt eine Fehlermeldung zurück, wenn diese nicht synchron sind. Die Grundannahme dieses Prozesses ist in Ordnung, steht aber in der Praxis im völligen Widerspruch zur Zero-Downtime-Philosophie. Abbildung 1 zeigt dies in der Praxis.
Magento überprüft Modulversionen zum Zeitpunkt der Anfrage in gutem Glauben; es versucht schlichtweg, hilfreich zu sein. Wenn wir natürlich vergessen haben, den Befehl setup:upgrade während eines Deployments auszuführen, sollten wir darüber entsprechend informiert werden. Dennoch sollte es schlichtweg einen besseren Weg geben, ein solches Szenario zu behandeln. Dieser Fehler wird nicht nur angezeigt, wenn sich die DB-Versionen hinter den Modulen auf der Festplatte befinden, sondern zeigt auch das gleiche Verhalten, wenn diese eine aktuellere Version enthalten.
Dies ist absolut unerwünscht, da fast alle Datenbankänderungen rückwärtskompatibel durchgeführt werden können, so dass sowohl alter als auch neuer Code mit den neuen Datenbankänderungen funktioniert. Es gibt eine bessere Möglichkeit, Datenbankänderungen durchzuführen, die wir im folgenden Abschnitt dieses Artikels behandeln werden.
Erreichen von Zero Downtime mit Magento Commerce
Wenn wir Magento's setup:upgrade (und damit sein Modul-Versionierungssystem) nicht verwenden können, um Datenbankänderungen auszulösen, dann müssen wir nach etwas anderem suchen. Hier können uns ausgereifte Bibliotheken von Drittanbietern helfen. Wie immer gibt es für dieses Problem bereits eine robuste Lösung in der Community außerhalb von Magento. Phinx ist zum Beispiel ein Paket für Datenbankmigrationen, das Folgendes bietet:
- Schema-Änderungen
- Datenänderungen
- Versionierung der Datenbank
- Einfache Rollbacks
Mit einem schlanken Wrapper, mit freundlicher Genehmigung des MX_PhinxMigrations Inviqa-Moduls, können wir Datenbank-Updates auslösen, ohne Magentos integrierten Mechanismus von Setup-Skripten verwenden zu müssen.
Das Schöne an dieser Lösung ist, dass Magento sich der Änderungen in der Datenbank überhaupt nicht bewusst ist und weiterhin Traffic bedient, vorausgesetzt, wir tun nichts Dummes, wie das Löschen einer Tabelle, auf die in unserem Code verwiesen wird.
Es gibt zwar Beispiele und Anweisungen im Modul selbst, aber wir möchten hier dennoch zeigen, wie der neue Workflow nach der Installation in Ihrer Magento-Instanz in etwa aussehen wird:
- Führen Sie bin/phinx create aus, um eine neue Datenbank-Migrationsdatei hinzuzufügen.
- Phinx wird Sie fragen, in welchem Ihrer Magento-Module Sie die Migrationsdatei erstellen möchten (es wird nach allen etc/migrations Ordnern in Ihren Modulen gesucht, also erstellen Sie zuerst einen dieser Ordner).
- Nachdem die Migrationsdatei erstellt wurde, können Sie Ihre Datenbankänderungen nach Bedarf schreiben und sogar die notwendigen Änderungen für ein Rollback bereitstellen.
- Führen Sie bin/phinx migrate während Ihres Deployment Prozesses, sofort nach bin/magento setup:upgrade, aus, um Datenbankänderungen anzuwenden (vergessen Sie auch nicht, bin/phinx migrate als Teil Ihrer lokalen Umgebungsbereitstellung auszuführen).
- Im Falle eines Rollbacks können Sie bin/phinx rollback ausführen, wodurch die zuletzt durchgeführte Migration rückgängig gemacht wird.
Wie genau hilft uns dies dabei, Blue-Green- und Zero-Time Deployments zu erreichen?;
Nun, wenn wir nie die Modulversionen ändern, dann können wir jederzeit Container mit altem Code und Container mit neuem Code haben, von denen jeder 100% kompatibel ist, weil die Modulversionen zwischen Datenbank und Code übereinstimmen.
Es ist erwähnenswert, wie wichtig es ist, setup:upgrade weiterhin als Teil Ihres Workflows auszuführen (für den Fall, dass Drittanbieter oder Magento-Module aktualisiert werden) und nie Ihre zugeschnittenen Modulversionen in den module.xml Dateien zu ändern, da dies das Problem eines Fehlabgleichs der Modulversionen verursacht, das wir bereits in diesem Artikel diskutiert haben, wodurch möglicherweise Ausfallzeiten auftreten werden.
Caches und Magento Commerce
Ein weiterer problematischer Aspekt von Zero-Downtime und Blue-Green-Implementierungen ist das Caching von Daten in Magento. Magento ermöglicht nativ verschiedene Arten von Caching, aber die häufigste in einer Produktionsumgebung angewandte Form ist ein In-Memory-Cache wie Redis.
In containerbasierten Umgebungen betreiben wir Redis und Magento in getrennten Containern, so dass wir während des Deployments nur unsere Magento-Container austauschen müssen. Dies stellt ein Problem für Blue-Green Deploys dar, da wir, wenn wir während des Deployment-Prozesses HTTP-Verkehr von alten und neuen Containern bedienen, möglicherweise ungültige Cache-Daten erzeugen könnten, je nachdem, welcher Container die Anfrage bearbeitet.
Um dieses Problem zu umgehen, verwenden wir verschiedene Redis-Datenbanken für unsere neuen und alten Container. Mit etwas einfachem Scripting in unserem Deployment-Prozess wechseln wir bei der Deploymenterstellung zwischen den beiden verfügbaren Redis-Datenbanken.
Wir können diesen Prozess besser verstehen, indem wir ihn in die folgenden Schritte unterteilen:
- Erstellung eines neuen Magento-Image auf dem Build-Server.
- Bestimmung der Redis-Datenbank-Nummer, die derzeit von den Live-Containern verwendet wird.
- Erstellung neuer Container aus dem neu erstellten Image unter Angabe der alternativen Redis-Datenbanknummer.
- Deployment der neuen Behälter im Blue-Green Zyklus (1 neuen Behälter hinzufügen, 1 alten Behälter entfernen)
- Deployment abgeschlossen
Mit dem obigen Prozess sind wir nun in der Lage, HTTP-Requests sowohl auf neuen als auch auf alten Containern zu verarbeiten, da diese unterschiedliche Redis-Datenbanken für ihren Cache verwenden. Der einzige Vorbehalt besteht darin, sicherzustellen, dass die Redis-Instanz in der Lage ist, zwei Sets von Magento-Cache-Daten zu einem beliebigen Zeitpunkt zu speichern.
Aktuelle Einschränkungen und Nachteile
Jeder Ansatz hat seine Grenzen und auch hier gibt es einige sorgfältig erwägte und akzeptierte Einschränkungen. Diese sind wie folgt:
- Das Aktualisieren von Magento-Modulen von Drittanbietern und Kernmodulen (z.B. bei der Aktualisierung von Magento selbst) führt zu einigen Ausfallzeiten, da sich die Modulversionen auf der Festplatte ändern.
- Um das Beste aus diesem Ansatz für Zero-Downtime-Implementierungen herauszuholen, ist es besser, Module von Drittanbietern wo immer möglich und sinnvoll zu vermeiden.
- Eine geringe Menge an Skripting ist erforderlich, um die Verwendung von zwei Redis-Datenbanken für das Caching alter und neuer Daten während des Deployment-Prozesses sicherzustellen.
- Eine größere Redis-Instanz ist erforderlich, um die doppelte Datenmenge zwischenspeichern zu können.
Zusammenfassung zu Magento Commerce
Während Magento's Datenbankmigrationsmechanismus eine herausfordernde Umgebung für Zero-Downtime und Blue-Green-Implementierungen darstellt, gibt es wie immer viel Spielraum für Kreativität.
Das MX_PhinxMigrations Modul steckt nach wie vor in den Kinderschuhen und irgendwann in der Zukunft möchten wir mit einer engeren Integration mit Magento experimentieren, um unter anderem folgende Funktionen anzubieten:
- Automatisches Anwenden von Phinx-Migrationen nach
setup:upgrade
wird ausgeführt. - Integration von Phinx-Befehlen (
migrate, rollback
etc.) in dasbin/magento
Tool.
Schließlich würde ich mir eine offiziell anerkannte Lösung für Zero-Downtime-Implementierungen von Magento wünschen, aber in der Zwischenzeit bietet die MX_PhinxMigrations eine viel einfachere Möglichkeit, Datenbankschemaänderungen innerhalb unserer Deployments zu handhaben.
Hier finden Sie den Blogpost in englischer Originalfassung.