Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Tipp
Dieser Inhalt ist ein Auszug aus dem eBook .NET Microservices Architecture for Containerized .NET Applications, verfügbar auf .NET Docs oder als kostenlose herunterladbare PDF, die offline gelesen werden kann.
Eine wichtige Regel für die Microservices-Architektur ist, dass jeder Microservice seine Domänendaten und -logik besitzen muss. Ebenso wie eine vollständige Anwendung ihre Logik und Daten besitzt, müssen also jeder Microservice seine Logik und Daten unter einem autonomen Lebenszyklus mit unabhängiger Bereitstellung pro Microservice besitzen.
Dies bedeutet, dass sich das konzeptionelle Modell der Domäne zwischen Subsystemen oder Microservices unterscheidet. Berücksichtigen Sie Unternehmensanwendungen, bei denen CRM-Anwendungen (Customer Relationship Management), Transaktionskaufsubsysteme und Kundensupport-Subsysteme jeweils auf einzigartige Attributen und Daten von Kundenentitäten zugreifen und jeweils einen anderen Gebundenen Kontext (Bounded Context, BC) verwenden.
Dieses Prinzip ist im domänengesteuerten Design (DDD) ähnlich, wobei jeder Bounded Context oder autonome Subsystem oder Dienst sein Domänenmodell (Daten plus Logik und Verhalten) besitzen muss. Jeder DDD Bounded Context korreliert mit einem Business Microservice (ein oder mehrere Dienste). Dieser Punkt zum Gebundenen Kontextmuster wird im nächsten Abschnitt erweitert.
Andererseits besteht der traditionelle (monolithische Daten) Ansatz, der in vielen Anwendungen verwendet wird, darin, eine einzige zentrale Datenbank oder nur wenige Datenbanken zu haben. Dies ist häufig eine normalisierte SQL-Datenbank, die für die gesamte Anwendung und alle internen Subsysteme verwendet wird, wie in Abbildung 4-7 dargestellt.
Abbildung 4-7. Vergleich der Datenhoheit: monolithische Datenbank im Vergleich zu Microservices
Im herkömmlichen Ansatz gibt es eine einzelne Datenbank, die für alle Dienste freigegeben ist, in der Regel in einer mehrstufigen Architektur. Im Microservices-Ansatz besitzt jeder Microservice sein Modell/seine Daten. Der zentralisierte Datenbankansatz sieht zunächst einfacher aus und scheint die Wiederverwendung von Entitäten in verschiedenen Subsystemen zu ermöglichen, um alles konsistent zu machen. Aber die Realität ist, dass Sie mit riesigen Tabellen enden, die viele verschiedene Subsysteme bedienen und Attribute und Spalten enthalten, die in den meisten Fällen nicht benötigt werden. Es ist wie der Versuch, die gleiche physische Karte zum Wandern auf einem kurzen Weg zu verwenden, einen Tagesausflug zu machen und geografie zu lernen.
Eine monolithische Anwendung mit einer einzigen relationalen Datenbank hat in der Regel zwei wichtige Vorteile: ACID-Transaktionen und die SQL-Sprache, die sowohl in allen Tabellen als auch in Daten im Zusammenhang mit Ihrer Anwendung verwendet werden. Dieser Ansatz ermöglicht das einfache Schreiben einer Abfrage, die Daten aus mehreren Tabellen kombiniert.
Der Datenzugriff wird jedoch viel komplizierter, wenn Sie zu einer Microservices-Architektur wechseln. Selbst bei verwendung von ACID-Transaktionen innerhalb eines Mikroservice oder gebundenen Kontexts ist es wichtig zu berücksichtigen, dass die Daten, die jedem Microservice gehören, privat für diesen Microservice sind und nur synchron über seine API-Endpunkte (REST, gRPC, SOAP usw.) oder asynchron über Messaging(AMQP oder ähnlich) zugegriffen werden sollten.
Durch die Kapselung der Daten wird sichergestellt, dass die Microservices lose gekoppelt sind und unabhängig voneinander weiterentwickelt werden können. Wenn mehrere Dienste auf dieselben Daten zugreifen, erfordern Schemaupdates koordinierte Updates für alle Dienste. Dies würde die Mikroservice-Lebenszyklusautonomie unterbrechen. Verteilte Datenstrukturen bedeuten jedoch, dass Sie keine einzelne ACID-Transaktion über Mikroservices hinweg herstellen können. Dies bedeutet wiederum, dass Sie die letztliche Konsistenz verwenden müssen, wenn ein Geschäftsprozess mehrere Microservices umfasst. Dies ist viel schwieriger zu implementieren als einfache SQL-Verknüpfungen, da Sie keine Integritätseinschränkungen erstellen oder verteilte Transaktionen zwischen separaten Datenbanken verwenden können, wie sie später erläutert werden. Ebenso sind viele andere relationale Datenbankfeatures für mehrere Microservices nicht verfügbar.
Unterschiedliche Microservices verwenden häufig unterschiedliche Arten von Datenbanken. Moderne Anwendungen speichern und verarbeiten verschiedene Arten von Daten, und eine relationale Datenbank ist nicht immer die beste Wahl. In einigen Anwendungsfällen verfügt eine NoSQL-Datenbank wie Azure CosmosDB oder MongoDB möglicherweise über ein komfortableres Datenmodell und bietet eine bessere Leistung und Skalierbarkeit als eine SQL-Datenbank wie SQL Server oder Azure SQL-Datenbank. In anderen Fällen ist eine relationale Datenbank immer noch der beste Ansatz. Daher verwenden Mikroservices-basierte Anwendungen häufig eine Mischung aus SQL- und NoSQL-Datenbanken, die manchmal als Polyglot-Persistenzansatz bezeichnet wird.
Eine partitionierte, polyglot-persistente Architektur für die Datenspeicherung hat viele Vorteile. Dazu gehören lose gekoppelte Dienste und bessere Leistung, Skalierbarkeit, Kosten und Verwaltbarkeit. Es können jedoch einige Herausforderungen bei der Verwaltung verteilter Daten entstehen, wie im späteren Verlauf dieses Kapitels näher erläutert wird: "Identifizieren von Domänenmodellgrenzen".
Die Beziehung zwischen Microservices und dem Gebundenen Kontextmuster
Das Konzept von Microservice leitet sich vom Bounded Context (BC)-Muster im domänengesteuerten Design (DDD) ab. DDD arbeitet mit großen Modellen, unterteilt diese in mehrere BCs und definiert explizite Umrisslinien. Jeder BC muss über ein eigenes Modell und eine eigene Datenbank verfügen; Ebenso besitzt jeder Microservice seine zugehörigen Daten. Darüber hinaus verfügt jede BC in der Regel über eine eigene allgegenwärtige Sprache , um die Kommunikation zwischen Softwareentwicklern und Domänenexperten zu unterstützen.
Diese Begriffe (hauptsächlich Domänenentitäten) in der allgegenwärtigen Sprache können unterschiedliche Namen in unterschiedlichen Gebundenen Kontexten haben, auch wenn verschiedene Domänenentitäten dieselbe Identität verwenden (d. a. die eindeutige ID, die zum Lesen der Entität aus dem Speicher verwendet wird). In einem begrenzten Kontext in einem Benutzerprofil verfügt die Entität „User domain“ beispielsweise über die gleiche Identität wie die Entität „Buyer domain“ im begrenzten Bestellkontext.
Ein Microservice ist daher wie ein gebundener Kontext, gibt aber auch an, dass es sich um einen verteilten Dienst handelt. Es wird als separater Prozess für jeden gebundenen Kontext erstellt und muss die zuvor aufgeführten verteilten Protokolle wie HTTP/HTTPS, WebSockets oder AMQP verwenden. Das Bounded Context-Muster gibt jedoch nicht an, ob es sich bei dem gebundenen Kontext um einen verteilten Dienst handelt oder ob es sich einfach um eine logische Grenze (z. B. ein generisches Subsystem) innerhalb einer monolithischen Bereitstellungsanwendung handelt.
Es ist wichtig hervorzuheben, dass das Definieren eines Diensts für jeden gebundenen Kontext ein guter Ausgangspunkt ist. Sie müssen Ihren Entwurf allerdings nicht darauf beschränken. Manchmal müssen Sie einen gebundenen Kontext oder einen Business Microservice entwerfen, der aus mehreren physischen Diensten besteht. Letztendlich sind beide Muster -Bounded Kontext und Mikroservice eng miteinander verbunden.
DDD profitiert von Microservices, indem es echte Grenzen in Form von verteilten Microservices erhält. Aber Ideen wie das Nicht-Teilen des Modells zwischen Microservices sind das, was Sie auch in einem Gebundenen Kontext wünschen.
Weitere Ressourcen
Chris Richardson. Muster: Datenbank pro Dienst
https://microservices.io/patterns/data/database-per-service.htmlMartin Fowler. BoundedContext
https://martinfowler.com/bliki/BoundedContext.htmlMartin Fowler. PolyglotPersistence
https://martinfowler.com/bliki/PolyglotPersistence.htmlAlberto Brandolini. Strategisches domänengesteuertes Design mit Kontextzuordnung
https://www.infoq.com/articles/ddd-contextmapping