Verwenden von asynchronem Messaging zur Verbesserung der Verfügbarkeit

Bild Hallo habrozhiteli! Wir haben kürzlich ein Buch von Chris Richardson an die Druckerei übergeben, um zu lehren, wie Anwendungen mithilfe der Microservice-Architektur erfolgreich entwickelt werden können. Das Buch behandelt nicht nur die Vorteile, sondern auch die Nachteile von Microservices. Sie erfahren, in welchen Situationen es sinnvoll ist, sie anzuwenden, und wann es besser ist, über einen monolithischen Ansatz nachzudenken.

Das Buch konzentriert sich auf Architektur und Design. Es richtet sich an alle Personen, deren Aufgaben das Schreiben und Bereitstellen von Software umfassen, einschließlich Entwickler, Architekten, technische Direktoren und Leiter der Entwicklungsabteilungen.

Das Folgende ist ein Auszug aus dem Buch Verwenden von asynchronem Messaging

Verwenden von asynchronem Messaging zur Verbesserung der Verfügbarkeit


Wie Sie gesehen haben, führen Sie die verschiedenen IPC-Mechanismen zu verschiedenen Kompromissen. Eine davon hängt damit zusammen, wie sich IPC auf die Barrierefreiheit auswirkt. In diesem Abschnitt erfahren Sie, dass die synchrone Interaktion mit anderen Diensten im Rahmen der Anforderungsverarbeitung die Verfügbarkeit der Anwendung verringert. In diesem Zusammenhang sollten Sie beim Entwerfen Ihrer Dienste nach Möglichkeit asynchrones Messaging verwenden.

Lassen Sie uns zunächst sehen, welche Probleme die synchrone Interaktion verursacht und wie sie sich auf die Barrierefreiheit auswirkt.

3.4.1. Synchronisierte Interaktion reduziert die Verfügbarkeit


REST ist eine äußerst beliebte IPC-Engine. Sie könnten versucht sein, es für die dienstübergreifende Kommunikation zu verwenden. Das Problem mit REST ist jedoch, dass es sich um ein synchrones Protokoll handelt: Der HTTP-Client muss warten, bis der Dienst eine Antwort zurückgibt. Jedes Mal, wenn die Dienste über ein synchrones Protokoll miteinander kommunizieren, wird die Verfügbarkeit der Anwendung verringert.

Um zu verstehen, warum dies geschieht, betrachten Sie das in Abb. 1 gezeigte Szenario. 3.15. Der Bestellservice verfügt über eine REST-API zum Erstellen von Bestellungen. Um die Bestellung zu überprüfen, wendet er sich an die Verbraucher- und Restaurantdienste, die ebenfalls über eine REST-API verfügen.

Bild

Das Erstellen einer Bestellung besteht aus dieser Abfolge von Schritten.

  1. Der Client sendet eine HTTP-POST- / Bestellanforderung an den Bestellservice.
  2. Der Bestellservice ruft Kundeninformationen ab, indem er eine HTTP-GET / consumer / id-Anfrage an den Consumer-Service sendet.
  3. Der Bestellservice ruft Restaurantinformationen ab, indem er eine HTTP-GET / Restaurant / ID-Anforderung an den Restaurantdienst ausführt.
  4. Order Taking prüft die Anfrage anhand von Informationen über den Kunden und das Restaurant.
  5. Auftragsannahme erstellt eine Bestellung.
  6. Order Taking sendet eine HTTP-Antwort an den Client.

Da diese Dienste HTTP verwenden, müssen alle für FTGO zugänglich sein, um die CreateOrder-Anforderung verarbeiten zu können. Es kann keine Bestellung erstellt werden, wenn mindestens einer der Dienste nicht verfügbar ist. Aus mathematischer Sicht ist die Verfügbarkeit eines Systembetriebs ein Produkt der Verfügbarkeit von Diensten, die daran beteiligt sind. Wenn der Bestellservice und die beiden von ihm aufgerufenen Services eine Verfügbarkeit von 99,5% haben, beträgt ihre Gesamtverfügbarkeit 99,5% 3 = 98,5%, was viel niedriger ist. Jeder nachfolgende Dienst, der an der Anforderung teilnimmt, macht den Vorgang weniger zugänglich.

Dieses Problem betrifft nicht nur REST-basierte Interaktionen. Die Verfügbarkeit nimmt ab, wenn ein Dienst Antworten von anderen Diensten erhalten muss, um auf einen Client zu antworten. Selbst der Übergang zu einem Anforderungs- / Antwort-Interaktionsstil über asynchrone Nachrichten hilft hier nicht weiter. Wenn der Bestelldienst beispielsweise über einen Broker eine Nachricht an den Verbraucherservice sendet und auf eine Antwort wartet, verschlechtert sich seine Verfügbarkeit.

Wenn Sie die Zugänglichkeit maximieren möchten, minimieren Sie den Umfang der synchronen Interaktion. Mal sehen, wie es geht.

3.4.2. Befreien Sie sich von synchroner Interaktion


Es gibt verschiedene Möglichkeiten, die synchrone Interaktion mit anderen Diensten bei der Verarbeitung synchroner Anforderungen zu reduzieren. Um dieses Problem vollständig zu vermeiden, können zunächst alle Dienste mit ausschließlich asynchronen APIs bereitgestellt werden. Dies ist jedoch nicht immer möglich. Beispielsweise entsprechen öffentliche APIs im Allgemeinen dem REST-Standard. Daher müssen einige Dienste über synchrone APIs verfügen.

Glücklicherweise ist es für die Verarbeitung synchroner Anforderungen nicht erforderlich, diese selbst auszuführen. Lassen Sie uns über solche Optionen sprechen.

Verwenden asynchroner Interaktionsstile

Im Idealfall sollte jede Interaktion in dem zuvor in diesem Kapitel beschriebenen asynchronen Stil erfolgen. Stellen Sie sich beispielsweise vor, der FTGO-Anwendungsclient verwendet einen Interaktionsstil für asynchrone Anforderungen und asynchrone Antworten, um Aufträge zu erstellen. Um eine Bestellung anzulegen, sendet er eine Anforderungsnachricht an den Bestellservice. Dieser Dienst tauscht dann asynchron Nachrichten mit anderen Diensten aus und gibt schließlich eine Antwort an den Client zurück (Abb. 3.16).

Bild

Der Client und der Dienst kommunizieren asynchron und senden Nachrichten über Kanäle. Keiner der Teilnehmer an dieser Interaktion ist blockiert und wartet auf eine Antwort.

Eine solche Architektur wäre äußerst robust, da der Broker Nachrichten puffert, bis ihr Verbrauch möglich ist. Das Problem ist jedoch, dass Dienste häufig über eine externe API verfügen, die ein synchrones Protokoll wie REST verwendet und daher sofort auf Anforderungen reagieren muss.

Wenn der Dienst über eine synchrone API verfügt, kann die Zugänglichkeit durch Datenreplikation verbessert werden. Mal sehen, wie es funktioniert.

Datenreplikation

Eine Möglichkeit, die synchrone Interaktion während der Abfrageverarbeitung zu minimieren, besteht darin, Daten zu replizieren. Der Dienst speichert eine Kopie (Replikat) der Daten, die zur Verarbeitung von Anforderungen benötigt werden. Um das Replikat auf dem neuesten Stand zu halten, werden Ereignisse abonniert, die von den Diensten veröffentlicht wurden, zu denen diese Daten gehören. Beispielsweise kann ein Bestelldienst eine Kopie von Daten speichern, die zu den Verbraucher- und Restaurantdiensten gehören. Auf diese Weise kann er Anfragen zum Erstellen von Bestellungen bearbeiten, ohne auf diese Dienste zurückgreifen zu müssen. Eine solche Architektur ist in Abb. 1 dargestellt. 3.17.

Bild

Die Verbraucher- und Restaurantdienste veröffentlichen Ereignisse, wenn sich ihre Daten ändern. Der Bestellservice abonniert diese Ereignisse und aktualisiert sein Replikat.

In einigen Fällen ist die Datenreplikation eine gute Lösung. In Kapitel 5 wird beispielsweise beschrieben, wie der Bestellservice Restaurant-Servicedaten repliziert, um Menüelemente überprüfen zu können. Einer der Nachteile dieses Ansatzes besteht darin, dass manchmal große Datenmengen kopiert werden müssen, was ineffizient ist. Wenn wir beispielsweise viele Kunden haben, kann es unpraktisch sein, eine Replik der Daten des Verbraucherdienstes zu speichern. Ein weiterer Nachteil der Replikation besteht darin, dass das Problem der Aktualisierung von Daten anderer Dienste nicht gelöst wird.

Um dieses Problem zu lösen, kann ein Dienst die Interaktion mit anderen Diensten verzögern, bis er auf seinen Client reagiert. Dies wird weiter diskutiert.

Beenden Sie die Verarbeitung, nachdem Sie eine Antwort zurückgegeben haben

Eine andere Möglichkeit, die synchrone Interaktion während der Abfrageverarbeitung zu eliminieren, besteht darin, diese Verarbeitung in Form der folgenden Schritte durchzuführen.

  1. Der Dienst prüft die Anfrage nur mit Hilfe lokal verfügbarer Daten.
  2. Es aktualisiert seine Datenbank, einschließlich des Hinzufügens von Nachrichten zur OUTBOX-Tabelle.
  3. Gibt die Antwort an den Client zurück.

Während der Verarbeitung der Anforderung greift der Dienst nicht synchron auf andere Dienste zu. Stattdessen sendet er ihnen asynchrone Nachrichten. Dieser Ansatz bietet eine schlechte Konnektivität von Diensten. Wie Sie im nächsten Kapitel sehen werden, wird dieser Prozess häufig als Erzählung implementiert.

Stellen Sie sich vor, der Bestellservice verhält sich so. Er erstellt eine Bestellung mit dem Status PENDING und überprüft diese, indem er asynchrone Nachrichten mit anderen Diensten austauscht. In Abb. Abbildung 3.18 zeigt, was passiert, wenn die Operation createOrder () aufgerufen wird. Die Kette der Ereignisse sieht so aus.

  1. Der Bestellservice erstellt eine Bestellung mit dem Status PENDING.
  2. Der Bestellservice gibt eine Antwort mit der Bestell-ID an seinen Kunden zurück.
  3. Der Bestelldienst sendet eine ValidateConsumerInfo-Nachricht an den Verbraucherdienst.
  4. Der Bestellservice sendet eine ValidateOrderDetails-Nachricht an den Restaurantdienst.
  5. Der Consumer-Service empfängt eine ValidateConsumerInfo-Nachricht, prüft, ob der Kunde eine Bestellung aufgeben kann, und sendet eine ConsumerValidated-Nachricht an den Order-Service.
  6. Der Restaurantdienst empfängt eine ValidateOrderDetails-Nachricht, überprüft die Richtigkeit der Menüelemente und die Fähigkeit des Restaurants, eine Bestellung an eine bestimmte Adresse zu liefern, und sendet eine OrderDetailsValidated-Nachricht an den Bestelldienst.
  7. Der Bestellservice empfängt ConsumerValidated- und OrderDetailsValidated-Nachrichten und ändert den Bestellstatus in VALIDATED.

Usw…

Der Bestellservice kann ConsumerValidated- und OrderDetailsValidated-Nachrichten in beliebiger Reihenfolge empfangen. Um zu wissen, welche er zuerst erhalten hat, ändert er den Status der Bestellung. Wenn die erste Nachricht ConsumerValidated war, ändert sich der Bestellstatus in CONSUMER_VALIDATED, und wenn OrderDetailsValidated in ORDER_DETAILS_VALIDATED geändert wird. Nach Erhalt der zweiten Nachricht setzt der Bestellservice den Bestellstatus auf VALIDATED.

Nach Überprüfung der Bestellung führt der Bestellservice die verbleibenden Schritte zum Erstellen der Bestellung aus, die im nächsten Kapitel erläutert werden. Ein großer Teil dieses Ansatzes besteht darin, dass der Bestellservice eine Bestellung erstellen und auf den Kunden reagieren kann, selbst wenn der Verbraucherservice nicht verfügbar ist. Früher oder später wird der Verbraucherservice alle ausstehenden Nachrichten wiederherstellen und verarbeiten, wodurch die Überprüfung der Bestellungen abgeschlossen wird.

Bild

Der Nachteil der Rückgabe einer Antwort vor der vollständigen Verarbeitung der Anforderung besteht darin, dass der Client dadurch komplexer wird. Wenn der Bestellservice beispielsweise eine Antwort zurückgibt, gibt er nur minimale Garantien für den Status der soeben erstellten Bestellung. Er antwortet sofort, noch bevor er die Bestellung überprüft und die Bankkarte des Kunden autorisiert. Um herauszufinden, ob die Bestellung erfolgreich erstellt wurde, muss der Kunde regelmäßig Informationen anfordern oder der Bestelldienst muss ihm eine Benachrichtigung senden. Trotz der Komplexität dieses Ansatzes lohnt es sich in vielen Fällen, ihn zu bevorzugen, insbesondere weil er die Probleme mit dem verteilten Transaktionsmanagement berücksichtigt, die wir in Kapitel 4 diskutieren werden. In den Kapiteln 4 und 5 werde ich diese Technik am Beispiel des Bestellservices demonstrieren.

Zusammenfassung


  • Die Microservice-Architektur ist verteilt, daher spielt die Interprozesskommunikation eine Schlüsselrolle.
  • Die Entwicklung des API-Dienstes muss sorgfältig und sorgfältig angegangen werden. Es ist am einfachsten, abwärtskompatible Änderungen vorzunehmen, da diese die Arbeitsweise der Kunden nicht beeinflussen. Wenn Sie wichtige Änderungen an der Service-API vornehmen, müssen Sie normalerweise sowohl die alte als auch die neue Version beibehalten, bis die Clients aktualisiert werden.
  • Es gibt viele IPC-Technologien mit jeweils eigenen Stärken und Schwächen. Die Schlüsselentscheidung in der Entwurfsphase ist die Wahl zwischen synchronem Remoteprozeduraufruf und asynchronen Nachrichten. Am einfachsten zu verwenden sind synchrone Protokolle wie REST, die auf dem Aufruf von Remoteprozeduren basieren. Um die Zugänglichkeit zu verbessern, sollten Dienste im Idealfall über asynchrones Messaging kommunizieren.
  • Um eine Lawinen-ähnliche Anhäufung von Fehlern im System zu verhindern, muss ein Client, der ein synchrones Protokoll verwendet, in der Lage sein, Teilausfälle zu bewältigen - die Tatsache, dass der aufgerufene Dienst entweder nicht verfügbar ist oder eine hohe Latenz aufweist. Insbesondere bei der Ausführung von Anforderungen ist es erforderlich, die Wartezeit zu zählen, die Anzahl überfälliger Anforderungen zu begrenzen und die Vorlage "Sicherung" anzuwenden, um Anrufe an den fehlerhaften Dienst zu vermeiden.
  • Eine Architektur, die synchrone Protokolle verwendet, muss einen Erkennungsmechanismus enthalten, damit Clients den Netzwerkstandort von Dienstinstanzen bestimmen können. Am einfachsten ist es, sich auf den von der Bereitstellungsplattform bereitgestellten Erkennungsmechanismus zu konzentrieren: auf die Vorlagen "Serverseitige Erkennung" und "Registrierung von Drittanbietern". Ein alternativer Ansatz ist die Implementierung der Serviceerkennung auf Anwendungsebene: die Vorlagen für die Clienterkennung und die Selbstregistrierung. Diese Methode erfordert mehr Aufwand, eignet sich jedoch für Situationen, in denen Dienste auf mehreren Bereitstellungsplattformen ausgeführt werden.
  • Das Nachrichten- und Kanalmodell kapselt die Details der Implementierung des Nachrichtensystems und wird eine gute Wahl beim Entwerfen dieser Art von Architektur. Später können Sie Ihre Architektur an eine bestimmte Messaging-Infrastruktur binden, für die normalerweise ein Broker verwendet wird.
  • Eine Hauptschwierigkeit beim Messaging ist die Veröffentlichung und Aktualisierung der Datenbank. Eine gute Lösung ist die Verwendung der Event Publishing-Vorlage: Die Nachricht wird ganz am Anfang als Teil der Transaktion in die Datenbank geschrieben. Ein separater Prozess ruft dann die Nachricht mithilfe der Vorlage "Interrogating Publisher" oder "Transactional Log Tracking" aus der Datenbank ab und leitet sie an den Broker weiter.

»Weitere Informationen zum Buch finden Sie auf der Website des Herausgebers
» Inhalt
» Auszug

Für Khabrozhiteley 30% Rabatt auf vorbestellte Bücher auf einen Gutschein - Microservices

Source: https://habr.com/ru/post/de458344/


All Articles