Kommunikation von Microservices – Die vier Ebenen der Entkopplung

1 Kommentar

Wenn man einführende Artikel zum Thema Microservices liest, so heißt es meist lapidar, dass Microservices über REST oder Messaging kommunizieren können (sollten). Die Frage, welche Kommunikation wann sinnvoll ist, wird meist zunächst nicht beantwortet. Dabei hat die Art der Kommunikation einen großen Impact auf die Vor- und Nachteile, die durch eine Microservices-Architektur entstehen.
Erklärtes Ziel einer Microservices-Architektur ist die Autonomie und Unabhängigkeit kleiner Anwendungen, die jeweils für eine bestimmte Fachlichkeit zuständig sind, deren Scope sich also an Bounded Context(en) ausrichtet. Damit die einzelnen Microservices möglichst autonom sind, müssen sie, so weit es geht, von anderen Services entkoppelt werden. In diesem Blogpost beschreibe ich die vier Ebenen der Entkopplung, die man mit Microservices erreichen kann, und für welche Anwendungsfälle sie jeweils Sinn ergeben.

Prämisse

Ich gehe davon aus, dass wir von Full-Stack-Microservices reden, die Persistenz und Fachlogik für einen bestimmten Bounded Context beinhalten. Vor kurzem bin ich mal wieder über eine Folie gestolpert, in der der Autor wie in der folgenden Grafik diverse Schichten aufgezeichnet hatte.

LayeredArchitecture

Wer das tatsächlich noch für eine gute Idee hält, sollte vielleicht erst einmal Was man vom Microservices-Hype (mindestens) mitnehmen sollte lesen, und Kaffeeküchengespräche: Microservices und Domain Driven Design kann auch nicht schaden.
Gut diskutieren kann man über den Punkt, ob Presentation immer mit in so einen Microservice gehört, oder ob das wieder eigene Microservices sind. Aber das ist nicht Thema dieses Posts.

Grundsätzlich haben wir in allen folgenden Ebenen separate Prozesse für jeden Microservice. Der Technologiestack eines Microservices ist ein Implementierungsinternum und kann je nach Anforderung sehr unterschiedlich aussehen. Wesentliche Punkte im Bereich Autonomie sind also bereits gegeben. Jetzt geht es darum, wie die Art der Kommunikation die Autonomie beeinflusst.

Arten der Kopplung

Ich unterscheide zwei Arten von Kopplungen, die ich im Folgenden kurz beschreibe.

Laufzeitkopplung

Eine Laufzeitkopplung ist gegeben, wenn zwei kommunizierende Services zur gleichen Zeit online sein müssen. Jederzeitiges Deployment ist dann nicht einfach möglich, man benötigt weitergehende Techniken wie Blue-Green-Deployments.

Organisatorische Kopplung – 2-Wege-Kommunikation vs. 1-Weg-Kommunikation

In der 2-Wege-Kommunikation wird eine Anfrage gestellt, auf die geantwortet wird. Für Frage und Antwort müssen jeweils Datenformate definiert werden, und meistens werden diese exklusiv für diese eine Schnittstelle definiert.
In der 1-Weg-Kommunikation gibt es nur einen Kommunikator, der ein Command oder Event schickt und keine Antwort erwartet.
Eine 1-Weg-Kommunikation ermöglicht eine stärkere Entkopplung als eine 2-Wege-Kommunikation.

Ebene 1: Synchrone Punkt-zu-Punkt-Verbindungen aka REST/SOAP über HTTP

  • Starke Laufzeitkopplung.
  • 2-Wege-Kommunikation.

Ebene1

In diesem konkreten Beispiel möchte ein Kunde ein Angebot für eine Lebensversicherung berechnen lassen. Der Lebenangebotsservice benötigt für die Berechnung allerdings das Geburtsdatum des Kunden und holt sich dieses über einen synchronen Aufruf des Partnerservices. Diese Art der Kommunikation ist wohl die am stärksten verbreitete.

Ebene 2: Asynchrone Punkt-zu-Punkt-Verbindungen aka Messaging über Queues

  • Keine Laufzeitkopplung.
  • 2-Wege-Kommunikation.

Ebene2

Auch hier möchte der Kunde ein Angebot berechnen lassen. Der Partnerservice wird nun über eine asynchrone Schnittstelle aufgerufen, in diesem Beispiel über eine Message in einer Queue. Der Lebenangebotsservice wiederum horcht auf eine Reply-Queue, und wenn der Partner das Geburtsdatum liefert, wird die Berechnung angestoßen und das Ergebnis anschließend zum Client gepusht. Dieses Vorgehen stellt neue Anforderungen an den Client. Gut nutzbar für Use-Cases, in denen Backend-Verarbeitungen länger dauern und der Kunde eh kein unmittelbares Feedback erwartet.

Ebene 3: Asynchrone Broadcasts aka Messaging über Topics

  • Keine Laufzeitkopplung.
  • 1-Weg-Kommunikation.

Ebene3

Hier schickt der Lebenangebotsservice ein AngebotAngefordertEvent, auf das sich andere Services registrieren können. Im Beispiel ist das ein Druckservice, der ein PDF mit dem Angebot erzeugt, und ein Kundenmanagementservice, der Daten darüber sammelt, wer welche Angebote angefordert hat. Sinnvoll also bei Fire-and-Forget-Szenarien.

Ebene 4: Datenduplikation über asynchrone Broadcasts

  • Keine Laufzeitkopplung.
  • 1-Weg-Kommunikation.

Ebene4

Hier schließt sich der Kreis: Wir haben den gleichen Use Case wie in Ebene 1. Der Lebenangebotsservice dupliziert allerdings nun das Geburtsdatum der Kunden in der eigenen Datenhaltung und kann so schnell antworten, ohne weitere Services aufzurufen. Die Information erhält er vom Partnerservice, der bei Partneränderungen ein PartnerChangedEvent schickt. Der Partnerservice behält so die Datenhoheit über das Geburtsdatum, aber der Lebenangebotsservice kann dieses Datum effektiv nutzen.

Fazit

Häufig wird nur die Ebene 1 verwendet, was kritisch ist, da man so automatisch wieder zu einer Layered Architecture mit synchronen Aufrufkaskaden kommt. Wenn man über Microservices und echte Entkopplung redet, darf man die Ebenen 2 bis 4 nicht aus dem Blick verlieren. Vor allem Ebene 4 wird häufig komplett ignoriert, da Datenduplikation in vielen Unternehmen ein Tabu ist. Das eigentlich zu lösende Problem in Bezug auf Daten ist allerdings die Datenhoheit – es darf nur einen geben, der die Daten ändern darf. Wenn das sichergestellt ist, ist es egal, an wie vielen Stellen das Datum dupliziert wird.

Tobias Flohre

Tobias Flohre arbeitet als Senior-Softwareentwickler/Architekt bei der codecentric AG. Seine Schwerpunkte sind Java-Enterprise-Anwendungen und Architekturen mit JEE/Spring. Er ist Autor diverser Artikel und schreibt regelmäßig Blogbeiträge zu den Themen Architektur und Spring. Zurzeit beschäftigt er sich mit Integrations- und Batch-Themen im Großunternehmen sowie mit modernen Webarchitekturen.

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

Kommentare

  • 21. April 2016 von Michael

    Guten Tag Herr Flohre,

    Vielen Dank für Ihren Artikel. Dieser war sehr aufschlussreich, da ich mich derzeit im Rahmem meines Studiums auch mit Microservices auseinadersetzen muss und mich Frage, wie Microservices untereinader Daten austauschen können und sollen.
    Bisher bin ich davon ausgegangen das ein Microservice am bestem unabhängig von anderen Microservices arbeiten sollte mit einer eigenen GUI. Dies ist aber nicht immer möglich wie in Ihrem Beispiel, weil es oftmals vorkommt das man auf Datensätze verschiedener Microservices zugreifen muss um zum Beispiel eine Liste zu rendern.

    Beispiel: Ich habe einen Microservice der für die Suche von Angebotene Autos zuständig ist.
    Das Suchergebnis wird in Form einer Listen mit verschiedenen Parameter ausgegeben wie z.B. teile des Angebots ,Ansprechpartner, das Automodell, der Hersteller, welche selber Microservices sind.
    Was ist Ihres erachtens die beste Art der Kopplung?

    P.s. Ich bin leider noch nicht so tief in der Materie das ich weiss wie man eMicroservices am beste schneiden sollte.

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.