Freigeben über


Identifizieren von Microservice-Grenzen

Azure DevOps

Was ist die richtige Größe für einen Microservice? Oft hören Sie etwas zu dem Effekt von "nicht zu groß und nicht zu klein" - und obwohl das sicher richtig ist, ist es in der Praxis nicht sehr hilfreich. Aber wenn Sie mit einem sorgfältig gestalteten Domänenmodell beginnen, ist es viel einfacher, über Microservices zu gründen.

Diagramm der gebundenen Kontexte.

In diesem Artikel wird ein Drohnen-Lieferdienst als laufendes Beispiel verwendet. Weitere Informationen zum Szenario und zur entsprechenden Referenzimplementierung finden Sie hier.

Vom Domänenmodell zu Microservices

Im vorherigen Artikel haben wir einen Satz gebundener Kontexte für eine Drone Delivery-Anwendung definiert. Anschließend haben wir einen dieser gebundenen Kontexte, den gebundenen Kontext "Versand" genauer untersucht und eine Reihe von Entitäten, Aggregaten und Domänendiensten für diesen gebundenen Kontext identifiziert.

Jetzt sind wir bereit, vom Domänenmodell zum Anwendungsdesign zu wechseln. Hier ist ein Ansatz, mit dem Sie Mikroservices vom Domänenmodell ableiten können.

  1. Beginnen Sie mit einem gebundenen Kontext. Im Allgemeinen sollte die Funktionalität in einem Microservice nicht mehr als einen gebundenen Kontext umfassen. Standardmäßig kennzeichnet ein gebundener Kontext die Grenze eines bestimmten Domänenmodells. Wenn Sie feststellen, dass ein Microservice verschiedene Domänenmodelle miteinander kombiniert, ist dies ein Zeichen, dass Sie möglicherweise zurückkehren und Ihre Domänenanalyse verfeinern müssen.

  2. Sehen Sie sich als Nächstes die Aggregate in Ihrem Domänenmodell an. Aggregate sind häufig gute Kandidaten für Microservices. Ein gut gestaltetes Aggregat zeigt viele der Merkmale eines gut gestalteten Mikroservice, z. B.:

    • Ein Aggregat wird von geschäftlichen Anforderungen und nicht von technischen Bedenken wie Datenzugriff oder Messaging abgeleitet.
    • Ein Aggregat sollte einen hohen funktionalen Zusammenhalt aufweisen.
    • Ein Aggregat ist eine Grenze der Persistenz.
    • Aggregate sollten lose gekoppelt sein.
  3. Domänendienste sind auch gute Kandidaten für Microservices. Domänendienste sind zustandslose Vorgänge über mehrere Aggregate hinweg. Ein typisches Beispiel ist ein Workflow, der mehrere Microservices umfasst. Wir sehen ein Beispiel dafür in der Drone Delivery-Anwendung.

  4. Berücksichtigen Sie schließlich nicht funktionale Anforderungen. Sehen Sie sich Faktoren wie Teamgröße, Datentypen, Technologien, Skalierbarkeitsanforderungen, Verfügbarkeitsanforderungen und Sicherheitsanforderungen an. Diese Faktoren können dazu führen, dass Sie einen Microservice weiter in zwei oder mehr kleinere Dienste zerlegen oder das Gegenteil tun und mehrere Microservices in einem kombinieren.

Nachdem Sie die Microservices in Ihrer Anwendung identifiziert haben, überprüfen Sie Ihr Design anhand der folgenden Kriterien:

  • Jeder Dienst hat eine einzige Verantwortung.
  • Es gibt keine Chatnachrichten zwischen Diensten. Wenn das Aufteilen von Funktionen in zwei Dienste bewirkt, dass sie übermäßig chatty sind, kann es ein Symptom sein, dass diese Funktionen in denselben Dienst gehören.
  • Jeder Dienst ist klein genug, damit er von einem kleinen Team erstellt werden kann, das unabhängig arbeitet.
  • Es gibt keine Abhängigkeiten, für die mindestens zwei Dienste im Sperrschritt bereitgestellt werden müssen. Es sollte immer möglich sein, einen Dienst bereitzustellen, ohne andere Dienste erneut bereitzustellen.
  • Dienstleistungen sind nicht eng gekoppelt und können unabhängig voneinander weiterentwickelt werden.
  • Ihre Dienstgrenzen verursachen keine Probleme mit der Datenkonsistenz oder Integrität. Manchmal ist es wichtig, die Datenkonsistenz aufrechtzuerhalten, indem Funktionen in einen einzelnen Microservice eingefügt werden. Das heißt, überlegen Sie, ob Sie wirklich starke Konsistenz benötigen. Es gibt Strategien zur Bewältigung der eventuellen Konsistenz in einem verteilten System, und die Vorteile von Dekompilierungsdiensten überwiegen häufig die Herausforderungen der Verwaltung der eventuellen Konsistenz.

Vor allem ist es wichtig, pragmatisch zu sein, und denken Sie daran, dass domänengesteuertes Design ein iterativer Prozess ist. Beginnen Sie im Zweifelsfall mit grobkörnigen Microservices. Das Aufteilen eines Microservice in zwei kleinere Dienste ist einfacher als die Umgestaltung von Funktionen über mehrere vorhandene Microservices hinweg.

Beispiel: Definieren von Mikroservices für die Drone Delivery-Anwendung

Erinnern Sie sich daran, dass das Entwicklungsteam die vier Aggregate - Delivery, Package, Drone und Account - und zwei Domänendienste, Scheduler und Supervisor identifiziert hatte.

Lieferung und Paket sind offensichtliche Kandidaten für Microservices. Der Scheduler und Supervisor koordinieren die Aktivitäten anderer Microservices, sodass es sinnvoll ist, diese Domänendienste als Microservices zu implementieren.

Drohnen und Account sind interessant, weil sie zu anderen gebundenen Kontexten gehören. Eine Option ist, dass der Scheduler die Drohnen- und Account-gebundenen Kontexte direkt aufruft. Eine weitere Option besteht darin, Drohnen- und Account-Mikroservices innerhalb des gebundenen Kontexts des Versands zu erstellen. Diese Microservices würden zwischen den gebundenen Kontexten vermitteln, indem APIs oder Datenschemas verfügbar sind, die für den Versandkontext besser geeignet sind.

Die Details der Drohnen- und Account-gebundenen Kontexte liegen außerhalb des Rahmens dieser Anleitung, daher haben wir in unserer Referenzimplementierung Simulierte Dienste für sie erstellt. Hier sind jedoch einige Faktoren, die in dieser Situation berücksichtigt werden sollten:

  • Was ist der Netzwerkaufwand für den direkten Aufruf in den anderen gebundenen Kontext?

  • Eignet sich das Datenschema für den anderen gebundenen Kontext für diesen Kontext, oder ist es besser, ein Schema zu haben, das auf diesen gebundenen Kontext zugeschnitten ist?

  • Ist der andere gebundene Kontext ein Legacysystem? Wenn ja, können Sie einen Dienst erstellen, der als Antibeschädigungsschicht fungiert, um zwischen dem älteren System und der modernen Anwendung zu übersetzen.

  • Was ist die Teamstruktur? Ist es einfach, mit dem Team zu kommunizieren, das für den anderen gebundenen Kontext verantwortlich ist? Wenn nicht, kann das Erstellen eines Diensts, der zwischen den beiden Kontexten vermittelt wird, dazu beitragen, die Kosten der teamübergreifenden Kommunikation zu verringern.

Bisher haben wir keine nicht funktionalen Anforderungen berücksichtigt. Im Hinblick auf die Anforderungen an den Durchsatz der Anwendung hat sich das Entwicklungsteam entschieden, einen separaten Mikroservice zu erstellen, der für die Aufnahme von Clientanforderungen verantwortlich ist. Dieser Microservice implementiert den Lastenausgleich , indem eingehende Anforderungen in einen Puffer für die Verarbeitung eingefügt werden. Der Scheduler liest die Anforderungen aus dem Puffer und führt den Workflow aus.

Nicht funktionale Anforderungen führten das Team dazu, einen zusätzlichen Dienst zu erstellen. Alle Dienstleistungen waren bisher über den Prozess der Planung und Lieferung von Paketen in Echtzeit. Das System muss aber auch die Historie jeder Lieferung im langfristigen Speicher zur Datenanalyse speichern. Das Team hielt dies für die Verantwortung des Lieferdiensts. Die Anforderungen an die Datenspeicherung unterscheiden sich jedoch für historische Analysen im Vergleich zu In-Flight-Vorgängen (siehe Datenüberlegungen). Daher hat sich das Team entschieden, einen separaten Übermittlungsverlaufsdienst zu erstellen, der auf DeliveryTracking-Ereignisse vom Übermittlungsdienst lauscht und die Ereignisse in einen langfristigen Speicher schreibt.

Das folgende Diagramm zeigt den Entwurf an diesem Punkt:

Diagramm, das das Design von Mikroservices für die Drone Delivery-Anwendung zeigt.

Laden Sie eine Visio-Datei dieser Architektur herunter.

Nächste Schritte

Zu diesem Zeitpunkt sollten Sie ein klares Verständnis des Zwecks und der Funktionalität jedes Mikroservice in Ihrem Design haben. Jetzt können Sie das System entwerfen.