Wann und wie man von Monolith zu Microservices wechselt. 7 Migrationsmuster / Sudo Null IT-News

Hey Habr! Ich bin Kirill Rozhdestvensky, Teamleiter im Unternehmen TCP-Soft. Ich bin zurück mit dem zweiten Teil einer Artikelserie über die Migration von einem Monolith zu Microservices. Ich möchte Sie daran erinnern, dass wir sie gemeinsam mit Kollegen aus vorbereiten Mango-Büromit denen wir ein gemeinsames Produkt erstellen, daher werden Artikel in ihrem Blog veröffentlicht.

Ich hinterlasse einen Link zum ersten Teil, in dem wir die Konzepte analysiert und festgestellt haben, wann es sich lohnt, auf Microservices umzusteigen, und wann nicht, ich werde gehen hier. In diesem Artikel werden wir die Übergangsmuster von einer monolithischen zu einer Microservice-Architektur analysieren.

Also, 7 Migrationsmuster.Würgegriff

Dieses Muster eignet sich, wenn wir einen Teil der Funktionalität schrittweise aus dem Monolith entfernen und gleichzeitig die Möglichkeit des Rollbacks vereinfachen möchten.

Nehmen wir an, wir haben einen Monolithen mit einem Modul, das zwei Methoden implementiert.

Wir beschließen, das Modul in einen Microservice zu verschieben. Wie setzen wir es um? Zunächst erstellen wir einen Einstiegspunkt (Proxy) zwischen dem Monolithen und dem Benutzer – das kann entweder eine fertige Lösung sein, zum Beispiel jedermanns Lieblings-Nginx, oder etwas Selbstgeschriebenes. In diesem Stadium ist der Proxy nur eine Schicht, die keine Logik enthält. Manchmal kann die Rolle eines Proxys vom Microservice selbst übernommen werden, aber diese Lösung wird nicht empfohlen, da der Microservice mit Logik geladen wird, die nichts mit der Geschäftsdomäne zu tun hat.

Als nächstes beginnen wir mit der Entwicklung unseres neuen Microservices.

Nachdem ein Teil der Funktionalität fertig und getestet ist, können wir den Dienst in Betrieb nehmen und den Proxy so konfigurieren, dass Benutzeranfragen für die übertragene Funktionalität an den Microservice gehen und alles andere den alten Weg geht – an den Monolithen.

Eine gute Praxis ist es, eine Art logischen Schalter hinzuzufügen (wo es keine Rolle spielt; es kann eine Konfiguration, ein Admin-Panel usw. sein) – der sogenannte Feature-Toggle, mit dem wir eine Implementierungsoption auswählen können. Dies ist vor allem für ein schnelles Rollback auf den Monolithen nützlich, wenn ein kritischer Fehler im Microservice erkannt wird.

Nachdem die Funktionalität getestet und der „Test by Combat“ bestanden wurde, kann sie aus dem Monolith entfernt werden.

Periodisch stellt sich die Frage, welche Teile der Funktionalität umgeschaltet werden sollen. Es ist in der Regel bequemer und sicherer, alle vom Microservice implementierten Funktionen vollständig umzuschalten. Dies liegt daran, dass es oft starke logische Beziehungen zwischen verschiedenen Methoden in derselben Geschäftsdomäne gibt. Und wenn die Daten aus irgendeinem Grund nicht zusammenlaufen und gleichzeitig eine Methode in einem Monolithen implementiert ist und die zweite sich bereits bewegt hat, kann die Suche nach der Ursache des Problems sehr kompliziert werden.

Kompositions-UI

Ein Muster, das unter Webentwicklern häufiger vorkommt, aber auch Desktop-Programmierer können es verwenden. Stellen wir uns vor, wir haben ein Webinterface mit Funktionen, die logisch in Module unterteilt werden können, zum Beispiel einbettbare Frames. Wir können den Übergang zu einer Microservice-Architektur beginnen, indem wir ein einzelnes Modul (z. B. das am wenigsten wichtige oder am wenigsten angesehene) in einen separaten Dienst verschieben.

Die Architektur kann wie folgt aussehen: Frontend – Abschnitte auf der Website “News” und “Rating der besten Spieler”, Backend – News- und Rating-Module. Wir betten einen Kontextmanager (Proxy) darin ein und entwickeln einen Bewertungs-Microservice. Danach leitet der Proxy die entsprechenden Anfragen direkt an den Microservice weiter. Es empfiehlt sich auch, einen Funktionsumschalter hinzuzufügen, mit dem Sie zurück zur Implementierung auf der Seite des Monolithen wechseln können. Erinnert sehr an “Schlinge”. Der einzige Unterschied besteht darin, dass hier die Schnittstelle auf der Seite des neuen Microservice gerendert wird.

Trennung durch Abstraktion

Die Vorlage eignet sich, wenn wir Funktionen aus dem Monolith entfernen möchten, die von verschiedenen Modulen aktiv verwendet werden. Beispielsweise gibt es ein monolithisches Backend mit Modulen für Deals und Anfragen, beide verwenden das E-Mail-Benachrichtigungsmodul, und wir möchten Benachrichtigungen in einem separaten Microservice isolieren. Dazu implementieren wir eine E-Mail-Sendeschnittstelle, mit der externe Module zu interagieren beginnen. Wir implementieren ein Gateway auf der Seite des Monolithen, um mit dem Microservice zu interagieren. Das Gateway implementiert eine neue Schnittstelle, aber parallel dazu verwenden wir weiterhin die alte Implementierung. Auf der Konfigurationsebene fügen wir einen Schalter hinzu, der die Implementierung von der guten alten monolithischen auf die neue Microservice-Implementierung umschaltet. Wir tauschen, testen, und wenn uns etwas nicht gefällt, schicken wir es zurück. Wenn alles passt, löschen wir die alte Implementierung und lassen nur das Gateway übrig.

Spion

Ein Muster für die Fälle, in denen wir gerade Funktionen entwickeln und der Microservice noch nicht vollständig implementiert wurde. Oder wenn wir uns zwischen einen Monolithen und einen Microservice einfügen müssen, um beispielsweise die Protokollierung durchzuführen.

Das Gateway leitet Anfragen an einen Stub mit derselben Schnittstelle wie der endgültige Microservice weiter. Es macht im Grunde nichts Sinnvolles, schreibt aber zum Beispiel etwas ins Log. Häufig findet in dieser Vorlage eine parallele Implementierung statt (z. B. das E-Mail-Benachrichtigungsmodul und das Gateway im Monolith arbeiten parallel).

Parallele Ausführung

Angenommen, wir haben ein algorithmisch komplexes Funktional. Wir wollen es umsetzen, aber gleichzeitig viele Fehler vermeiden. Dazu müssen wir die neue Funktionalität testen, bevor wir darauf umstellen.

Zunächst erstellen wir eine Proxy-Schicht zwischen dem Benutzer und der vorhandenen Funktionalität (genau wie wir es im Fall der „Schlinge“ getan haben). Als Nächstes entwickeln wir einen neuen Microservice, testen ihn und stellen ihn in einer Produktionsumgebung bereit. Wenn ein Benutzer eine Anfrage stellt (z. B. zum Generieren eines Berichts), wird die Anfrage auf Seiten des Einstiegspunkts dupliziert und gleichzeitig an die neue und die alte Implementierung gesendet. Es wird nur eine Antwort an den Benutzer zurückgegeben – diejenige, die den alten funktionierenden Dienst zurückgegeben hat (es wird keine Überraschungen geben). Die Ergebnisse werden verglichen, das Ergebnis wird ins Protokoll geschrieben. Es bleibt nur, das Protokoll zu beobachten, Unstimmigkeiten in Berichten zu erkennen und Fehler zu beheben. Wenn wir nach ein paar Wochen/Monaten zu dem Schluss kommen, dass in letzter Zeit nichts ins Log geschrieben wurde, dann können Sie auf eine neue Implementierung umsteigen.

Das oben beschriebene Muster ist ziemlich einfach, hat aber einige sehr offensichtliche Fallstricke. Erstens lädt zusätzliche Logik den Einstiegspunkt, was sich negativ auf die Leistung auswirken kann. Zweitens, wenn wir Anfragen synchron und sequentiell stellen, dann verlängert sich die Gesamtzeit für den Client, um eine Antwort zu erhalten (sie haben nach dem alten Dienst gefragt, gewartet, dann nach einem neuen gefragt, wieder gewartet).

Die Liste der Probleme endet hier nicht, aber sie sind alle lösbar. Hier sind einige Dinge, die Sie tun können, um sie zu beheben:

  • Schreiben Sie die ursprüngliche Anforderung in ein bestimmtes Protokoll (oder in eine Warteschlange im Nachrichtenbroker) und folgen Sie dann dem alten Pfad. Einige Dienste von Drittanbietern lesen das Protokoll (Warteschlange) mit einer bestimmten Häufigkeit, rufen die entsprechenden Methoden auf und analysieren die Ergebnisse.

  • Führen Sie zwei Anforderungen asynchron aus, ohne auf eine Antwort vom neuen Dienst zu warten.

Tatsächlich gibt es mehrere Lösungsmöglichkeiten, die alle von der jeweiligen Situation abhängen. Ich möchte nur betonen, dass dieses Muster ebenso gefährlich wie nützlich ist. Die Arbeit daran kann mit dem ungeschickten Umgang mit Waffen verglichen werden: Eine falsche Bewegung, und Sie können sich leicht in Ihr eigenes Glied schießen. Seid vorsichtig.

Canary-VeröffentlichungDie Redewendung „Kanarienvogel in der Mine“ bedeutet etwas, das Gefahr signalisiert.  Erschien während der Verwendung von Kanarienvögeln, um gefährliche Gase in Minen zu erkennen.Die Redewendung „Kanarienvogel in der Mine“ bedeutet etwas, das Gefahr signalisiert. Erschien während der Verwendung von Kanarienvögeln, um gefährliche Gase in Minen zu erkennen.

Die Vorlage impliziert die Freigabe der Funktionalität nur für einen Teil der Clients, um die Negativität im Fehlerfall zu reduzieren. Wenn wir eine neue Funktionalität, die mit einem neuen Microservice funktioniert, nur für einen Teil der Clients bereitstellen, werden im Falle eines Ausfalls nicht alle darunter leiden.

Sie können auf verschiedene Arten ausgleichen: Wählen Sie zufällige Kunden aus, geben Sie die treuesten eindeutig an, wählen Sie Gruppen nach geografischen Regionen aus. In jedem Fall ist es notwendig, die Wahl derjenigen, die überhaupt wechseln, mit Bedacht anzugehen. Wenn Sie beispielsweise 10 % der Kunden zufällig auswählen, kann es durchaus sein, dass alle VIPs, die 99 % der Last erzeugen, in diesen Anteil fallen. Dann wird sich die Freigabe im Wesentlichen als allgemein herausstellen, und von einer Verringerung der Unzufriedenheit kann nicht gesprochen werden.

Außerdem müssen Sie die Clients schrittweise wechseln: 10 %, 20 %, 40 % usw. Es kommt oft vor, dass Probleme nicht auftreten, wenn die Auslastung des Dienstes gering ist, und wenn Sie eine bestimmte kritische Schwelle überschreiten, z. B. bei 42%, explodiert alles.

Dekorateur

Nicht gerade ein Migrationsmuster, eher im Zusammenhang mit allgemeinen Mustern, aber es kann beim Wechsel zu Microservices nützlich sein. Zum Beispiel, wenn wir vor der Implementierung eines Microservices Daten über die Intensität der Nutzung der Funktionalität oder spezifische Anfragen sammeln möchten, die in Tests verwendet werden können.

Hier ist alles einfach. Wie üblich implementieren wir einen Einstiegspunkt, aber in diesem Fall reichern wir ihn auch mit der notwendigen Logik an. Beispielsweise analysieren wir die Häufigkeit von Anfragen oder berücksichtigen andere für uns interessante Metriken.

Damit ist der zweite Teil unserer Artikelserie zum Übergang vom Monolith zu Microservices abgeschlossen. Stellen Sie Ihre Fragen und teilen Sie Ihre Gedanken in den Kommentaren mit. Mein Spitzname, unter dem ich in den Kommentaren antworte: @vi_ki_ng. Im nächsten Teil werden wir die Möglichkeiten der Arbeit mit Daten und die Frage ihrer Synchronisation analysieren.

Abonnieren Sie unsere sozialen Netzwerke:

Mango Office-Konten

TCP-Soft-Konten

* Ein Produkt von Meta, einer anerkannten extremistischen Organisation in der Russischen Föderation

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *