Von Monolithen zu Microservices: Domain-Driven Design als Schlüssel zum Erfolg
Keine Kommentare

In vielen Unternehmen sind sie noch zu finden: monolithische Legacy-Systeme, die über Jahrzehnte gewachsen sind. Nach und nach stellen IT-Abteilungen die Alt-Systeme auf Microservices um. Dabei eignet sich nicht jedes System zur Migration, und auch bei der Integration bestehender Datenbanken gilt es einiges zu beachten.

Der Umstieg auf Microservices bringt viele Vorteile mit sich. Eines der Grundprinzipien in der Softwareentwicklung ist die Modularisierung. Bereits 1972 stellte David Parnas das Prinzip des „Information Hiding“ vor [1]. Die Grundidee hinter Modularisierung ist, ein Softwaresystem in Module mit begrenzter Komplexität und klaren Schnittstellen zu zerlegen. Die interne Business-Logik der Module bleibt dem Nutzer dabei verborgen. Dieses Prinzip der Modularisierung treiben Microservices auf die Spitze, indem sie jedes Element des Funktionsumfangs in einem eigenen Service auslagern (Abb. 1).

Abbildung 1: Die Grundidee von Microservices

Abbildung 1: Die Grundidee von Microservices

Was sind Microservices?

Microservices-Architekturen zeichnen sich durch fünf Kerneigenschaften aus:

Bounded Context: Der Funktionsumfang einer Anwendung wird in fachlich abgrenzbare Kontexte (Bounded Context) geschnitten. Gemäß dem Prinzip „Do One Thing and Do It Well” hat jeder Kontext genau eine funktionale Aufgabe. Aus technischer Sicht wird je Kontext ein Service implementiert, der sowohl für die Datenhaltung als auch für die Business-Logik und das User Interface verantwortlich ist. Ein Entwicklungsteam bestehend aus maximal zehn Personen setzt jeweils einen Service um.

Lose Kopplung: Die Kopplung von Microservices erfolgt lose und anders als bei konventionellen Modularisierungstechniken, bei denen Funktionen in Bibliotheken und Klassen, welche im selben Prozess laufen, ausgelagert werden. Microservices hingegen werden separat in eigenen Prozessen ausgeführt und über das Netzwerk, zum Beispiel auf Basis von RESTful HTTP, miteinander gekoppelt.

Unabhängige Deploybarkeit: Entwicklungsteams können Services weitestgehend unabhängig voneinander in die Produktion überführen. Voraussetzung dafür ist ein guter fachlicher Schnitt der Anwendung. Außerdem unterstützen leichtgewichtige Virtualisierungstechniken wie Docker die einfache Bereitstellung der Services. Jedes Team arbeitet innerhalb einer eigenen Deployment-Pipeline (Continuous Integration/Continuous Development) und hat somit den Build-Prozess und die Absicherung des Service in der eigenen Hand. Lediglich einige wenige Integrationstests müssen übergreifend durchgeführt werden.

Unabhängige Technologie-Stacks: Da die Integration der Services in ein Gesamtsystem lose gekoppelt über das Netzwerk erfolgt, ist ein gemeinsamer Technologie-Stack nicht erforderlich. Jeder Service lässt sich mit einer eigenen Technologie wie etwa Programmiersprache, Frameworks,  Datenbank, Betriebssystem oder Laufzeitumgebung umsetzen. Die Technologieentscheidung liegt beim jeweiligen Entwicklungsteam. Somit wird ein optimal auf den jeweiligen Funktionsumfang zugeschnittener Stack erreicht (Stichwort: „best fit“).

Dezentrales Datenmanagement: Jeder Service verwaltet seine für den Funktionsumfang notwendigen Daten selbst. Dies führt zu einer Verteilung und Dezentralisierung der Daten über das Gesamtsystem. Vor diesem Hintergrund müssen die Entwickler Strategien bezüglich Datenkonsistenz, Dauerhaftigkeit und Datenreplikation ausarbeiten.

API Conference 2019

Oliver Drotbohm

REST Beyond the Obvious – API Design for Ever Evolving Systems

mit Oliver Drotbohm (Pivotal Software, Inc.)

Arne Limburg

API-Kompatibilität durch Consumer-Driven Contracts

mit Arne Limburg (OPEN KNOWLEDGE GmbH)

 

Wann ein bestehendes IT-System in Microservices überführen?

Der immer noch anhaltende Microservice-Hype und die vielen offensichtlichen Vorteile lassen vermuten, dass jedes IT-System von Microservices profitiert. Sie bringen aber auch Nachteile mit sich. Der größte Nachteil ist, dass durch die Verwendung von Microservices ein verteiltes System mit hoher Komplexität entsteht. Serviceaufrufe zwischen Microservices sind fehleranfällig und sollten entsprechend robust entwickelt sein. Außerdem entstehen mehr Artefakte, die es zu installieren und betreiben gilt. Unabhängig von der Technik gibt es auch Herausforderungen auf organisatorischer Ebene. Entscheidungskompetenzen und Verantwortung sind auf die Teams verteilt. Es ist somit nicht sinnvoll, jede bestehende monolithische Applikation in Microservices zu überführen.

Microservices spielen vor allem dort ihre Vorteile aus, wo neue oder geänderte Features schnell ausgeliefert werden müssen. Sie passen daher optimal zu agilen Vorgehensmodellen. Das Gesamtsystem lässt sich mit Hilfe von Microservices viel besser hinsichtlich verwendeter Technologien, Datenhaltung und Skalierbarkeit optimieren. Zusätzlich entsteht eine nachhaltige Softwarearchitektur, die langfristig besser wartbar ist, da einzelne Microservices leicht angepasst und ersetzt werden können.

Schrittweise Portierung

Wenn genau diese Punkte bei einem bestehenden monolithischen System Probleme bereiten, lohnt es sich, über die Migration auf eine Microservice-basierte Architektur nachdenken. Ein kompletter Umbau eines Monolithen in einem Schritt innerhalb kurzer Zeit („big bang“) wird nur bei sehr kleinen Anwendungen funktionieren. Bei größeren Anwendungen kommt in der Regel nur eine schrittweise Portierung auf Microservices in Frage, um einerseits schnell Erfolge zu erzielen und andererseits das Risiko für das Scheitern des Umbaus zu minimieren. Im ersten Schritt können einzelne Funktionen in einen Microservice ausgelagert werden. Stufenweise können die Entwickler den Umfang an Microservices dann erhöhen (Abb. 2). Bereits bei der Migration eines einzelnen Service kommen erste Vorteile direkt zum Tragen, wie zum Beispiel ein schnelles Deployment unabhängig vom Rest der Anwendung sowie eine flexible und autonome Entwicklung des Service.

Die folgenden Best Practices beschreiben, wie die Herangehensweise an einen schrittweisen Umbau aussehen sollte, um die maximalen Potentiale einer Microservice-basierten Architektur auszuschöpfen.

Abbildung 2: Schrittweise Migration

Abb. 2: Schrittweise Migration

Mit Domain-Driven Design zu einem guten fachlichen Schnitt

Der Schnitt in fachlich abgrenzbare Kontexte mit klarer Aufgabe ist entscheidend für die erfolgreiche Umsetzung einer Microservices-Architektur. Denn nur bei gutem Schnitt sind Teams in der Lage, neue Funktionalitäten unabhängig voneinander zu entwickeln und in Produktion zu bringen. Doch gerade dieser funktionale Schnitt fällt Entwicklungsteams für komplexe Systeme häufig nicht leicht. Grund hierfür ist in vielen Fällen das fehlende Know-how der Fachdomäne sowie ein technisch geprägter Schnitt der Anwendung, etwa in Frontend, Business-Logik und Datenhaltung.

Lesen Sie auch: DDD mit PHP – Bausteine für erfolgreiches Domain-driven Design

Insbesondere bei Legacy-Systemen, die über Jahre gewachsen sind, fehlt oft die Dokumentation der umgesetzten Geschäftslogik. Vor der schrittweisen Migration zu einer Microservices Architektur steht die Modellierung der Geschäftsobjekte und -prozesse. Sie ist die Voraussetzung für einen sinnvollen fachlich motivierten Schnitt, der zu lose gekoppelten Services führt. Häufig lässt sich durch diese nachträgliche Modellierung von Bestandssystemen die Business-Logik vereinfachen. Projektteams begründen die komplexe Geschäftslogik oftmals damit, dass der Festplattenspeicher im Rechenzentrum zu dieser Zeit teuer war oder Erweiterungen angedacht waren, die nie zur Umsetzung kamen.

Die Fachdomäne korrekt abbilden

Für die Modellierung der fachlichen Zusammenhänge eines Systems hat sich das Domain-driven Design (DDD) als Vorgehensmodell bewährt [2],[3],[4]. DDD verfolgt das Ziel, die Fachdomäne mit ihren Geschäftsobjekten und -prozessen korrekt abzubilden und eine einheitliche domänenspezifische Sprache, die sogenannte „Ubiquitous Language“ zu schaffen.

Im ersten Schritt der Domänenmodellierung modelliert das Team gemeinsam mit den Domänenexperten und der Entwicklung die beteiligten Geschäftsobjekte und deren Beziehungen. Hieraus entsteht ein erstes Domänenmodell, welches die geschäftskritischen Objekte sowie deren Abhängigkeiten zueinander darstellt. Abbildung 3 zeigt das Ergebnis dieser Phase am Beispiel einer Versionsverwaltung.

Abbildung 3: Ein erstes Domänenmodell am Beispiel einer Versionsverwaltung

Abbildung 3: Ein erstes Domänenmodell am Beispiel einer Versionsverwaltung

 

Der zweite Schritt verfolgt das Ziel, die fachlich abgrenzbaren Umfänge („Bounded Contexts“) des Domänenmodells festzulegen. Die Kontexte sollten hierbei so gewählt sein, dass die Abhängigkeiten zwischen ihnen möglichst gering sind. Ein Negativ-Beispiel wäre der technisch-geprägte Schnitt in eine Datenhaltung (DB) und verschiedene Logik-Bausteine, der zu eng aneinander gekoppelten Services führt. Gibt es Änderungen, ziehen diese Anpassungen in diversen Services nach sich. Die Teams sind somit nicht in der Lage, Umfänge ohne längere Abstimmungen zu liefern. Use Cases beziehungsweise Szenarien können helfen, Abhängigkeiten zwischen Business-Objekten zu erkennen und eine gute Unterteilung in Kontexte vorzunehmen.

Abbildung 4: Definition der Bounded Contexts im Domänenmodell

Abbildung 4: Definition der Bounded Contexts im Domänenmodell

 

 

Auf der anderen Seite sollte die Anzahl der Objekte innerhalb eines Kontexts so gewählt sein, dass eine Umsetzung durch ein einzelnes Entwicklerteam möglich ist und nicht auf mehrere Teams aufgeteilt werden muss. Das heißt ein sogenannter „Big Ball of Mud“, also ein Kontext mit sehr hoher Anzahl an Objekten, ist zu vermeiden. Ansonsten geht der Vorteil der unabhängigen Entwicklung und Deploybarkeit verloren. Abbildung 4 zeigt die Aufteilung in Kontexte am Beispiel der Versionsverwaltung.

Innerhalb eines Bounded Contexts verwenden die Entwickler als einheitliche Fachsprache die Ubiquitous Language. Die so eingeführten Begrifflichkeiten nutzen alle Projektbeteiligten, also Entwickler, Tester oder Domänenexperten, von der Anforderung bis in die Umsetzung innerhalb der Software.

Context Mapping zur Modellierung der Schnittstellen

Die Realisierung eines Bounded Contexts erfolgt idealerweise als unabhängiger Microservice mit eigenem Technologiestack und eigener Datenhaltung. Dieser ist nur über eine Web-Schnittstelle auf Basis von RESTfull HTTP ansprechbar. Die Modellierung der Schnittstellen zwischen den einzelnen Bounded Contexts und somit auch der Services erfolgt im Rahmen des Context Mappings. Domain-driven Design stellt hierfür verschiedene Muster bereit (für eine vollständige Übersicht siehe [3]).

Ein verbreitetes Muster ist der Customer-Supplier. Hierbei stellt der Lieferant dem Kunden die benötigten Informationen über eine Schnittstelle bereit (Abb. 5). Wie diese aussehen soll, bestimmen beide gemeinsam. Sie legen auch fest, welche Geschäftsobjekte mit deren jeweiligen Attributen der Lieferant bereitstellt. Eine Variation dieses Musters ist der Conformist (Mitläufer), bei dem sich der Kunde den Vorgaben des Lieferanten anpasst und kein Mitspracherecht bei der Gestaltung der Schnittstelle hat.

Lesen Sie auch: „DDD, Event-Sourcing und CQRS ergänzen sich ausgezeichnet“ – Interview mit Golo Roden

Als Standard für die Implementierung von Schnittstellen (APIs) der Muster Customer-Supplier und Conformist hat sich RESTfull HTTP etabliert. In der Praxis gibt es jedoch einige Qualitätsunterschiede der REST APIs. Im einfachsten Fall wird nur HTTP als Transportkanal verwendet, was aber nicht alle Potentiale des HTTP-Protokolls ausschöpft. Damit ein REST API zum Erfolg führt, sollte dieses in Anlehnung an die Geschäftsobjekte, das heißt Ressourcen-orientiert entwickelt werden. Jedes Geschäftsobjekt sollte durch eine URL ansprechbar sein. Des Weiteren empfiehlt es sich, zur Realisierung des API vorhandene Standards des HTTP-Protokolls wie Statuscodes und Funktionen (u.a. GET, POST, PUT) zu verwenden, da diese allgemein bekannt sind. Andere Entwickler verstehen das API auf diese Weise schnell. Schnittstellen zwischen Microservices können so in kürzester Zeit entwickelt werden. Mit dem sogenannten „Richardson Maturity Model“ lässt sich der Reifegrad eines REST API bestimmen [5].

Abbildung 5: Context Mapping mit Customer-Supplier aus [4]

Abbildung 5: Context Mapping mit Customer-Supplier aus [4]

 

Ein weiteres Muster ist der „Shared Kernel“, bei dem zwei Kontexte (Teams) sich einige Modellelemente teilen (Abb. 6). Bei der Entwicklung der Services ist keine Schnittstelle notwendig. Stattdessen wird ein Teil des Codes sowie der Datenbank gemeinsam genutzt. Ein Vorteil davon ist, dass doppelter Code vermieden wird. Die Wahl dieses Musters sollte aber gut überlegt sein, denn es entsteht ein hoher Abstimmungsaufwand zwischen den Teams bezüglich Umsetzung und Pflege der gemeinsamen Objekte. Ein vollständig unabhängiges Deployment der Microservices ist bei diesem Muster nicht möglich.

Abbildung 6: Context Mapping mit Shared Kernel aus [4]

Abbildung 6: Context Mapping mit Shared Kernel aus [4]

Besser geeignet ist dann häufig das Muster „Separate Ways“. Hierbei werden Geschäftsobjekte redundant und gegebenenfalls in unterschiedlicher Ausprägung in Kontexten umgesetzt (Abb. 7). Die Entwicklung der Microservices erfolgt in diesem Fall vollständig unabhängig. Die Nachteile, die aufgrund des redundanten Codes und der redundanten Datenhaltung entstehen, können vernachlässigt werden, wenn eine schnelle Auslieferung von neuen oder geänderten Features im Anwendungskontext zwingend notwendig ist. Separate Ways kommt daher immer dann in Frage, wenn es wirtschaftlicher ist, Elemente mehrfach vorzuhalten, als sie über Services hinweg abzustimmen und zu synchronisieren.

Abbildung 7: Context Mapping mit Separate Ways aus [4]

Abbildung 7: Context Mapping mit Separate Ways aus [4]

 

 

Von einer zentralen zu einer verteilten Datenhaltung

Bei monolithischen Legacy-Systemen gibt es in der Regel eine zentrale Datenhaltung auf Basis einer relationalen Datenbank, in der alle Geschäftsobjekte gespeichert sind. Typischerweise wird in größeren Projekten die Datenhaltungsschicht in die Verantwortung eines Datenbank-Teams gegeben, das sich um Themen wie Namenskonventionen und Modellierung des zentralen Datenmodells kümmert. Um neue oder geänderte Features zu entwickeln, sind häufig Änderungen am Datenmodell notwendig. Da jede Änderung mit dem Datenbank-Team abgestimmt werden muss, entsteht ein Flaschenhals in der Entwicklung, der das schnelle Ausliefern neuer oder geänderter Features verhindert.

Mit Hilfe der bei einer Domänenmodellierung nach DDD identifizierten Bounded Contexts lässt sich das zentrale Datenmodell eines Monolithen in kleinere Datenmodelle zerlegen. Abbildung 8 zeigt eine beispielhafte schrittweise Überführung in eine verteilte Datenhaltung. Die Realisierung der verteilten Datenhaltung kann auf verschiedene Weise erfolgen. Im einfachsten Fall verwenden die Entwickler je Microservice ein separates Schema in einer relationalen Datenbank. Damit ist die Unabhängigkeit der Datenmodelle bereits ausreichend gewährleistet. Themen wie Betrieb, Aktualisierung und Backup der Datenbank sind weiterhin zentral möglich. Wird mehr Flexibilität benötigt, können in einer Microservice-basierten Architektur auch unterschiedliche Datenbank-Technologien wie zum Beispiel dokumentenorientierte oder Graphdatenbanken zum Einsatz kommen. Für jeden Microservice kann abhängig vom Anwendungsfall die beste Technologie gewählt werden. Ein weiterer Vorteil ist, dass die Entwickler je Microservice spezifische Optimierungen hinsichtlich lesender und schreibender Zugriffe vornehmen können.

Durch die getrennte Datenhaltung ergeben sich aber auch Herausforderungen und Nachteile, die bei der Überführung eines Monolithen in Microservices zu beachten sind. Die Wahl beliebiger Technologien zur Realisierung der Datenhaltung kann dazu führen, dass viel spezifisches Know-how für das Gesamtsystem notwendig ist. Teammitglieder können in diesem Fall nicht mehr so einfach in andere Teams wechseln. Daher sollten verschiedene Technologien nur zum Einsatz kommen, wenn wirklich ein Nutzen daraus entsteht. Eine weitere Herausforderung sind Transaktionen. Bei einer zentralen Datenhaltung auf Basis von relationalen Datenbanken können innerhalb einer Transaktion beliebige Objekte verändert und Konsistenz sichergestellt werden. Die Datenbankmanagementsysteme erfüllen das sogenannte ACID-Prinzip (Atomarität, Konsistenz, Isolation, Dauerhaftigkeit).

IT Security Summit 2019

Sichere Logins sind doch ganz einfach!

mit Arne Blankerts (thePHP.cc)

Hands-on workshop – Hansel & Gretel do TLS

mit Marcus Bointon (Synchromedia Limited)

 

DevOps Docker Camp

Sie lernen die Konzepte von Docker und bauen Schritt für Schritt eine eigene Infrastruktur für und mit Docker auf.

Datenbank-übergreifende Transaktionen nach dem ACID-Prinzip sind in Microservice-basierten Architekturen nicht möglich. Es gibt verschiedene Alternativen damit umzugehen. Datenänderungen können etwa als ACID-basierte Transaktionen innerhalb eines Microservice stattfinden. Wenn die Datenänderungen auch für andere Microservices relevant sind, können diese per Event darüber informiert werden. Auf das Event kann dann je Microservice unterschiedlich reagiert werden. Die Verteilung der Events erfolgt typischerweise mit einer Messaging-Lösung im Publish/Subscribe-Verfahren, wodurch eine lose Kopplung zwischen den Microservices entsteht und die unabhängige Entwicklung weiterhin gewährleistet ist. Die Konsistenz des Gesamtsystems wird bei diesem Verfahren nicht sofort (synchron), sondern zu einem späteren Zeitpunkt erreicht (asynchron). Diese Art der Konsistenz wird auch als „eventual consistency“ bezeichnet und kommt bei vielen NoSQL-Datenbanken zum Einsatz.

Eine andere Möglichkeit, mit verteilten Transaktionen umzugehen, ist diese von vornherein zu vermeiden. Mit der Methode des DDD kann bei der Erstellung eines Domänenmodells darauf geachtet werden, dass Transaktionen nur innerhalb der Bounded Contexts stattfinden. Bei DDD verwenden Entwickler zu diesem Zweck sogenannte Aggregates. Jedes Aggregate fasst die Geschäftsobjekte zusammen, die aus fachlicher Sicht eng miteinander in Verbindung stehen und bei denen Konsistenz gewährleistet sein muss. Im Rahmen eines Bounded Contexts kann es mehrere Aggregates geben. So sind innerhalb eines Microservices ACID-Transaktionen möglich. Aus Anwendersicht hat das den Vorteil, dass es eine direkte (synchrone) Rückmeldung gibt. Aus Entwicklungssicht entsteht ein weniger komplexes Gesamtsystem.

Abbildung 8: Von einer zentralen zu einer verteilten Datenhaltung

Abbildung 8: Von einer zentralen zu einer verteilten Datenhaltung

 

Von einer zentralen zu einer verteilten Benutzeroberfläche

Bei einem monolithischen System gibt es in der Regel eine grafische Benutzeroberfläche (GUI), die entweder als Rich-Client oder Webanwendung realisiert ist. Ähnlich wie bei der Datenhaltung liegt die Verantwortung für die Entwicklung der GUI meistens bei einem Team. Da neue oder geänderte Features in vielen Fällen Anpassungen an der GUI mit sich bringen, ist fast immer eine Abstimmung mit diesem Team notwendig, sodass auch hier ein Flaschenhals für die Entwicklung besteht.

Bei der Überführung eines Monolithen in Microservices steht deshalb bezüglich der GUI die Entscheidung an, ob ein einheitliches Erscheinungsbild (Look & Feel) notwendig ist. Hierbei spielen die Anwender des Gesamtsystems eine entscheidende Rolle. Wenn ein Anwender das System so verwendet, dass mehrere Microservices angesprochen werden, beispielsweise bei einem Webshop, sollte ein einheitliches Erscheinungsbild gegeben sein. Das gewährleistet eine gute Benutzerfreundlichkeit der Anwendung. Wenn durch die fachliche Zerlegung des Monolithen mit DDD Microservices entstehen, die durch verschiedene Anwendergruppen verwendet werden, kann das Erscheinungsbild auch unterschiedlich realisiert werden.

Für die Entwicklung der GUI in Microservice-basierten Architekturen gibt es verschiedene Ansätze [6]. Grundsätzlich lassen sich die Ansätze in zwei Gruppen einteilen: Es gibt eine zentrale Komponente, welche die GUI-Module der einzelnen Microservices integriert. Oder aber, die GUI-Module der Microservices sind eigenständig deploybar und werden über Web-Links integriert.

Zur ersten Gruppe zählen vor allem Desktop-Anwendungen (Rich Clients) sowie mobile Anwendungen (Mobile Apps), die sich nur vollständig installieren lassen, sodass vor dem Deployment immer eine Integration der einzelnen GUI-Elemente notwendig ist. Auch Single-Page-Applikationen, die GUI-Module von mehreren Microservices integrieren, lassen sich nicht unabhängig voneinander deployen.

Um die vollen Vorteile von Microservices auszunutzen, sollten diese aber unabhängig deploybar sein. Nur so können Teams eigenständig neue Features entwickeln und schnell ausliefern. Hierfür können die Ansätze aus der zweiten Gruppe verwendet werden, die auf die Integration mit Hilfe von Web-Links setzen. Jeder Microservice bietet eine Web-basierte GUI, die als Single-Page-Applikation oder mit mehreren HTML-Seiten realisiert ist.

Bei der Entwicklung von eigenständigen GUIs besteht für das Gesamtsystem die Gefahr, dass ein unterschiedliches Look & Feel entsteht. Wenn eine einheitliche Benutzeroberfläche für den Anwendungsfall zwingend notwendig ist, sollten Artefakte wie zum Beispiel CSS-Dateien und Bilder über die Microservices synchronisiert werden. Die dabei entstehenden minimalen Abhängigkeiten zwischen den Microservices und Entwicklungsteams sind vernachlässigbar.

Das Beispiel in Abbildung 9 zeigt, wie sich ein monolithischer RichClient schrittweise in eine Microservice-basierte Webanwendung überführen lässt. Bei dieser müssen die Anwender damit zurechtkommen, dass es übergangsweise eine alte und eine neue GUI gibt.

Abbildung 9: Von einer zentralen zu einer verteilten Benutzeroberfläche

Abbildung 9: Von einer zentralen zu einer verteilten Benutzeroberfläche

Fazit

Nicht für jedes Projekt ist es sinnvoll, eine Migration zu einer Microservices-Architektur durchzuführen. Deshalb sollten alle Beteiligten im Vorfeld abklären, ob für eben dieses Projekt die Vorteile wie etwa Skalierbarkeit, unabhängiges Deployment oder schnelles Time-to-Market durch agile Entwicklung überwiegen. Vor einer erfolgreichen Umstellung steht immer der fachliche Schnitt auf Basis von DDD. Dieser minimiert Abhängigkeiten zwischen den Teams und Services. Das Zusammenfassen von Datenhaltung, Logik und Benutzeroberfläche innerhalb eines Service führt zu hoher Unabhängigkeit. Letztlich sind Microservices aber der perfekte Architekturstil, um monolithische Legacy-Systeme schrittweise und risikoarm zu modernisieren.

Links & Literatur

[1] Parnas, D. L.: On the Criteria To Be Used in Decomposing Systems into Modules. In: Communications of the ACM 15 (1972), Nr. 12

[2] Eric J. Evans, Domain-Driven Design: Tackling Complexity in the Heart of Software, Addison Wesley, 2003

[3] Vaughn Vernon, Implementing Domain-Driven Design, Addison Wesley, 2013

[4] Vaughn Vernon, Domain-Driven Design kompakt, dpunkt.verlag, 2017

[5] Martin Fowler, Richardson Maturity Model – steps toward the glory of REST, 2010, Weblink: https://martinfowler.com/articles/richardsonMaturityModel.html

[6] Eberhard Wolff, Microservices – Grundlagen flexibler Softwarearchitekturen, dpunkt.verlag, 2015

 

Unsere Redaktion empfiehlt:

Relevante Beiträge

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu:
X
- Gib Deinen Standort ein -
- or -