Muster: Microservice-Architektur
Kontext
Sie entwickeln eine serverseitige Unternehmensanwendung. Sie muss eine Vielzahl verschiedener Clients unterstützen, darunter Desktop-Browser, mobile Browser und native mobile Anwendungen. Die Anwendung stellt möglicherweise auch eine API zur Verfügung, die von Drittanbietern verwendet werden kann. Sie kann auch über Webdienste oder einen Nachrichtenbroker in andere Anwendungen integriert werden. Die Anwendung verarbeitet Anforderungen (HTTP-Anforderungen und -Nachrichten) durch Ausführen von Geschäftslogik. Zugriff auf eine Datenbank; Austausch von Nachrichten mit anderen Systemen; und Zurückgeben einer HTML / JSON / XML-Antwort. Es gibt logische Komponenten, die verschiedenen Funktionsbereichen der Anwendung entsprechen.
Problem
Wie sieht die Bereitstellungsarchitektur der Anwendung aus?
Kräfte
- An der Anwendung arbeitet ein Entwicklerteam.
- Neue Teammitglieder müssen schnell produktiv werden.
- Die Anwendung muss leicht verständlich sein und ändern
- Sie möchten die kontinuierliche Bereitstellung der Anwendung üben.
- Sie müssen mehrere Instanzen der Anwendung auf mehreren Computern ausführen, um die Anforderungen an Skalierbarkeit und Verfügbarkeit zu erfüllen.
- Sie möchten neue Technologien (Frameworks, Programmiersprachen usw.) nutzen.
Lösung
Definieren Sie eine Architektur, die die Anwendung als eine Reihe von lose gekoppelten Technologien strukturiert. Collaborating Services. Dieser Ansatz entspricht der Y-Achse des Scale Cube. Jeder Service ist:
- Sehr wartbar und testbar – aktiviert ra pid und häufige Entwicklung und Bereitstellung
- Lose Verbindung mit anderen Diensten – ermöglicht es einem Team, die meiste Zeit unabhängig an seinen Diensten zu arbeiten, ohne von Änderungen an anderen Diensten betroffen zu sein und ohne andere Dienste zu beeinträchtigen
- Unabhängig einsetzbar – ermöglicht es einem Team, seinen Service bereitzustellen, ohne sich mit anderen Teams abstimmen zu müssen.
- Kann von einem kleinen Team entwickelt werden – unerlässlich für eine hohe Produktivität, indem der hohe Kommunikationsaufwand eines großen Teams vermieden wird Teams
Dienste kommunizieren entweder über synchrone Protokolle wie HTTP / REST oder über asynchrone Protokolle wie AMQP. Dienste können unabhängig voneinander entwickelt und bereitgestellt werden. Jeder Dienst verfügt über eine eigene Datenbank von anderen Diensten entkoppelt werden. Die Datenkonsistenz zwischen Diensten wird mithilfe des Saga-Musters beibehalten.
Um mehr über die Art eines Dienstes zu erfahren, lesen Sie bitte diesen Artikel.
Beispiele
Fiktive E-Commerce-Anwendung on
Stellen Sie sich vor, Sie erstellen eine E-Commerce-Anwendung, die Bestellungen von Kunden entgegennimmt, den Lagerbestand und das verfügbare Guthaben überprüft und diese versendet. Die Anwendung besteht aus mehreren Komponenten, einschließlich der StoreFrontUI, die die Benutzeroberfläche implementiert zusammen mit einigen Backend-Diensten zum Überprüfen des Guthabens, zum Verwalten des Inventars und der Versandaufträge. Die Anwendung besteht aus einer Reihe von Diensten.
Zeigen Sie mir den Code
. Sehen Sie sich die von Chris Richardson entwickelten Beispielanwendungen an. Diese Beispiele auf Github veranschaulichen verschiedene Aspekte der Microservice-Architektur.
Resultierender Kontext
Vorteile
Diese Lösung bietet eine Reihe von Vorteilen:
- Ermöglicht die kontinuierliche Bereitstellung und Bereitstellung großer, komplexer Anwendungen.
- Verbesserte Wartbarkeit – Jeder Dienst ist relativ klein und daher leichter zu verstehen und zu ändern.
- Bessere Testbarkeit – Dienste sind kleiner und schneller zu testen.
- Bessere Bereitstellbarkeit – Dienste kann unabhängig bereitgestellt werden
- Sie können den Entwicklungsaufwand für mehrere autonome Teams organisieren. Jedes Team (so genannte zwei Pizza) besitzt und ist für einen oder mehrere Dienste verantwortlich. Jedes Team kann seine Services unabhängig von allen anderen Teams entwickeln, testen, bereitstellen und skalieren.
- Jeder Microservice ist relativ klein:
- Einfacher für a Entwickler verstehen
- Die IDE ist schneller und macht Entwickler produktiver
- Die Anwendung startet schneller, was Entwickler produktiver macht und Bereitstellungen beschleunigt
- Verbesserte Fehlerisolation. Wenn beispielsweise in einem Dienst ein Speicherverlust auftritt, ist nur dieser Dienst betroffen. Die anderen Dienste verarbeiten weiterhin Anforderungen. Im Vergleich dazu kann eine sich schlecht verhaltende Komponente einer monolithischen Architektur das gesamte System zum Erliegen bringen.
- Eliminiert jegliche langfristige Bindung an einen Technologie-Stack. Wenn Sie einen neuen Service entwickeln, können Sie einen neuen Technologie-Stack auswählen. Wenn Sie größere Änderungen an einem vorhandenen Service vornehmen, können Sie ihn auch mithilfe eines neuen Technologie-Stacks neu schreiben.
Nachteile
Diese Lösung weist eine Reihe von Nachteilen auf:
- Entwickler müssen sich mit der zusätzlichen Komplexität beim Erstellen eines verteilten Systems auseinandersetzen:
- Entwickler müssen den Kommunikationsmechanismus zwischen Diensten implementieren und sich mit Teilfehlern befassen.
- Das Implementieren von Anforderungen, die sich über mehrere Dienste erstrecken, ist schwieriger.
- Das Testen der Interaktionen zwischen Diensten ist schwieriger schwierig
- Die Implementierung von Anforderungen, die mehrere Dienste umfassen, erfordert eine sorgfältige Koordination zwischen den Teams.
- Entwicklertools / IDEs sind auf die Erstellung monolithischer Anwendungen ausgerichtet und bieten keine explizite Unterstützung für die Entwicklung verteilter Anwendungen.
- Komplexität der Bereitstellung. In der Produktion besteht auch die betriebliche Komplexität der Bereitstellung und Verwaltung eines Systems, das aus vielen verschiedenen Diensten besteht.
- Erhöhter Speicherverbrauch. Die Microservice-Architektur ersetzt N monolithische Anwendungsinstanzen durch NxM-Service-Instanzen. Wenn jeder Dienst in einer eigenen JVM (oder einer gleichwertigen JVM) ausgeführt wird, die normalerweise zum Isolieren der Instanzen erforderlich ist, entsteht ein M-mal so viele JVM-Laufzeiten. Wenn jeder Dienst auf einer eigenen VM (z. B. einer EC2-Instanz) ausgeführt wird, wie dies bei Netflix der Fall ist, ist der Overhead sogar noch höher.
Probleme
Es gibt Viele Probleme, die Sie angehen müssen.
Wann wird die Microservice-Architektur verwendet?
Eine Herausforderung bei der Verwendung dieses Ansatzes besteht darin, zu entscheiden, wann die Verwendung sinnvoll ist. Bei der Entwicklung der ersten Version von In einer Anwendung haben Sie häufig nicht die Probleme, die durch diesen Ansatz gelöst werden. Darüber hinaus verlangsamt die Verwendung einer ausgeklügelten, verteilten Architektur die Entwicklung. Dies kann ein großes Problem für Startups sein, deren größte Herausforderung häufig darin besteht, das Geschäftsmodell und die damit verbundenen Funktionen schnell weiterzuentwickeln Anwendung. Die Verwendung von Y-Achsen-Teilungen kann die schnelle Iteration erheblich erschweren. Später jedoch, wenn die Herausforderung in der Skalierung besteht und Sie eine funktionale Zerlegung verwenden müssen, können die verworrenen Abhängigkeiten die Zerlegung Ihrer monolithischen Anwendung erschweren eine Reihe von Diensten.
So zerlegen Sie die Anwendung
Eine weitere Herausforderung besteht darin, zu entscheiden, wie das System in Microservices aufgeteilt werden soll. Dies ist eine Kunst, aber es gibt eine Reihe von Strategien, die helfen können:
- Nach Geschäftsfähigkeit zerlegen und Dienste definieren, die den Geschäftsfähigkeiten entsprechen.
- Nach domänengesteuerter Entwurfsunterdomäne zerlegen.
- Nach Verb oder Anwendungsfall zerlegen und Dienste definieren, die für bestimmte Aktionen verantwortlich sind . z.B. a
Shipping Service
, das für den Versand vollständiger Bestellungen verantwortlich ist Art. z.B. eineAccount Service
, die für die Verwaltung von Benutzerkonten verantwortlich ist.
Idealerweise sollte jeder Dienst nur eine geringe Anzahl von Verantwortlichkeiten haben. (Onkel) Bob Martin spricht über das Entwerfen von Klassen unter Verwendung des Single Responsibility Principle (SRP). Das SRP definiert die Verantwortung einer Klasse als Grund für Änderungen und gibt an, dass eine Klasse nur einen Grund für Änderungen haben sollte. Es ist sinnvoll, das SRP auf das Service-Design anzuwenden
Eine weitere Analogie, die beim Service-Design hilft, ist das Design von Unix-Dienstprogrammen. Unix bietet eine große Anzahl von Dienstprogrammen wie grep, cat und find. Jedes Dienstprogramm macht genau eine Sache, oft außergewöhnlich gut. und soll mit anderen Dienstprogrammen mithilfe eines Shell-Skripts kombiniert werden, um komplexe Aufgaben auszuführen.
Wie wird die Datenkonsistenz aufrechterhalten?
Um eine lose Kopplung sicherzustellen, hat jeder Dienst seinen eigenen Die Aufrechterhaltung der Datenkonsistenz zwischen Diensten ist eine Herausforderung, da dies bei 2-Phasen-Commit- / verteilten Transaktionen nicht der Fall ist Eine Option muss stattdessen das Saga-Muster verwenden. Ein Dienst veröffentlicht ein Ereignis, wenn sich seine Daten ändern. Andere Dienste verwenden dieses Ereignis und aktualisieren ihre Daten. Es gibt verschiedene Möglichkeiten, Daten zuverlässig zu aktualisieren und Ereignisse zu veröffentlichen, einschließlich Ereignisbeschaffung und Tailing des Transaktionsprotokolls.
So implementieren Sie Abfragen?
Eine weitere Herausforderung besteht darin, Abfragen zu implementieren, die Daten abrufen müssen, die mehreren Diensten gehören.
- Die API CQRS-Muster (Composition and Command Query Responsibility Segregation).
Es gibt viele Muster, die mit dem Microservices-Muster zusammenhängen. Die monolithische Architektur ist eine Alternative zur Microservice-Architektur. Die anderen Muster behandeln Probleme, die beim Anwenden der Microservice-Architektur auftreten.
- Zerlegungsmuster
- Nach Geschäftsfähigkeit zerlegen
- Nach Subdomäne zerlegen
- Das Muster Datenbank pro Dienst beschreibt, wie die einzelnen Muster dargestellt werden Der Dienst verfügt über eine eigene Datenbank, um eine lose Kopplung sicherzustellen.
- Das API-Gateway-Muster definiert, wie Clients in einer Microservice-Architektur auf die Dienste zugreifen.
- Die clientseitigen Erkennungs- und serverseitigen Erkennungsmuster werden verwendet, um Anforderungen für einen Client an einen weiterzuleiten verfügbare Dienstinstanz in einer Microservice-Architektur.
- Die Aufrufmuster für Messaging und Remoteprozedur sind zwei verschiedene Arten, wie Dienste kommunizieren können.
- Die Muster für einen einzelnen Dienst pro Host und mehrere Dienste pro Host Zwei verschiedene Bereitstellungsstrategien.
- Querschnittsthemen: Microservice-Chassis-Muster und externe Konfiguration
- Testmuster: Service-Komponententest und Service-Integrationsvertragstest
- Breaker
- Zugriffstoken
- Beobachtbarkeitsmuster:
- Protokollaggregation
- Anwendungsmetriken
- Überwachungsprotokollierung
- Verteilte Ablaufverfolgung
- Ausnahmeverfolgung
- API für Integritätsprüfung
- Bereitstellungen und Änderungen protokollieren
- UI-Muster:
- Serverseitige Seitenfragmentzusammensetzung
- Clientseitige UI-Zusammensetzung
Bekannte Verwendungszwecke
Die meisten großen Websites, einschließlich Netflix, Amazon und eBay, haben sich von einer monolithischen Architektur zu einer Microservice-Architektur entwickelt.
Netflix ist ein sehr beliebter Video-Streaming-Dienst, der dafür verantwortlich ist Für bis zu 30% des Internetverkehrs verfügt das Unternehmen über eine große, serviceorientierte Architektur. Sie verarbeiten täglich über eine Milliarde Anrufe an ihre Video-Streaming-API von über 800 verschiedenen Gerätetypen. Jede API ruft durchschnittlich sechs Fans an Aufrufe von Backend-Diensten.
Amazon.com hatte ursprünglich eine zweistufige Architektur. Zur Skalierung wurden sie auf eine serviceorientierte Architektur migriert, die aus Hunderten von Backend-Diensten besteht. Mehrere Anwendungen rufen diese Dienste einschließlich der Anwendungen auf die die Amazon.com-Website und die Webdienst-API implementieren. Die Amazon.com-Websiteanwendung ruft 100-150 Dienste auf, um die zu erhalten Daten, die zum Erstellen einer Webseite verwendet wurden.
Die Auktionsseite ebay.com hat sich ebenfalls von einer monolithischen Architektur zu einer serviceorientierten Architektur entwickelt. Die Anwendungsebene besteht aus mehreren unabhängigen Anwendungen. Jede Anwendung implementiert die Geschäftslogik Für einen bestimmten Funktionsbereich wie Kaufen oder Verkaufen. Jede Anwendung verwendet X-Achsen-Teilungen und einige Anwendungen wie Suchen verwenden Z-Achsen-Teilungen. Ebay.com wendet auch eine Kombination aus X-, Y- und Z-Skalierung auf die an Datenbankebene.
Es gibt zahlreiche andere Beispiele für Unternehmen, die die Microservice-Architektur verwenden.
Chris Richardson hat Beispiele für Microservices-basierte Anwendungen.
Siehe auch
Siehe meine Code Freeze 2018-Keynote, die eine gute Einführung in die Microservice-Architektur bietet.