Read in English · Leer en español · Lire en français
Abschnitt 6.2 von 6.8 · Mittelstufe · 22 Min. Lesezeit
Servicebasierte Architektur und serviceorientierte Architektur
Videolektion
6 Min. · auf Englisch gesprochen, mit UntertitelnNur anhören (Audio)
Transkript lesen
Viele reale Systeme liegen zwischen einem Monolithen und vielen Microservices. In dieser Lektion lernen Sie die servicebasierte Architektur kennen, den pragmatischen Mittelweg, und die ältere serviceorientierte Architektur, mit der sie oft verwechselt wird.
Denken Sie an ein Krankenhaus, das aus einem Gebäude herauswächst. Es könnte sich in Hunderte winziger Praxen aufteilen, jede mit eigenem Empfang und eigenem Archiv. Oder es könnte in fünf Abteilungen in getrennten Flügeln umziehen: Geburtshilfe, Chirurgie, Ambulanz, Apotheke und Notaufnahme. Jeder Flügel hat sein eigenes Personal und kann renoviert werden, ohne die anderen zu schließen. Aber alle teilen sich weiterhin ein zentrales Patientenarchiv. Das ist servicebasierte Architektur: wenige große, getrennte Teile, die sich jeweils um einen ganzen Geschäftsbereich kümmern und sich oft noch eine Datenbank teilen.
Servicebasierte Architektur teilt ein System in wenige separat deployte, grobgranulare Domain Services auf, typischerweise zwischen vier und zwölf. Jeder deckt einen ganzen Geschäftsbereich ab, etwa Bestellungen oder Zahlungen. Daraus folgen zwei Dinge. Die meisten Abläufe laufen innerhalb eines Service und können daher eine gewöhnliche lokale Datenbanktransaktion mit vollen ACID-Garantien nutzen: atomar, konsistent, isoliert und dauerhaft. Und die Services rufen sich selten gegenseitig auf, was synchrone Ketten kurz hält.
Hier ist eine Essenslieferplattform, die so aufgebaut ist. Oben sind vier Benutzeroberflächen: die Kunden-App, das Restaurant-Tablet, die Kurier-App und ein Betriebsportal. Sie rufen eine optionale API-Schicht auf, einen Reverse Proxy oder ein Gateway, das Routing, Authentifizierung und Rate Limits übernimmt. Dahinter liegen fünf Domain Services. Jeder ist grobgranular, mit allem, was seine Domäne braucht, von der API bis zum Datenzugriff, und jeder gehört einem Team. Vier davon teilen sich eine PostgreSQL-Datenbank mit je einem Schema, und jeder Service darf nur sein eigenes anfassen. Das Teilen macht den Stil günstig und einfach, ist aber auch seine Hauptschwäche, weil Schemaänderungen koordiniert werden müssen. Zahlungen behält eine eigene Datenbank, weil Kartendaten einen triftigen Grund liefern, und lässt sich so allein auditieren. Einem Service nur dann einen eigenen Speicher zu geben, wenn das gerechtfertigt ist, ist eine Möglichkeit, die gemeinsame Datenbank zu zähmen.
Warum diesen Stil wählen? Stellen Sie sich vor, das Unternehmen ist auf fünf Teams gewachsen, etwa fünfunddreißig Entwicklerinnen und Entwickler. Sein Monolith ist gut organisiert, aber Releases sind zur Warteschlange geworden, und ein Fehler im Kurier-Tracking hat zweimal den Checkout lahmgelegt. Mit fünf Domain Services läuft eine Bestellung innerhalb des Bestellservice in einer lokalen Transaktion und macht dann einen Aufruf an Zahlungen. Die anderen Services erfahren von der Bestellung über eine Nachricht, nicht über eine Kette von Aufrufen. Das bringt fünf getrennte Release-Pipelines. Ein Tracking-Fehler stoppt den Checkout nicht mehr, und jedes Team liefert aus, wenn es so weit ist. Es kostet fünf Sätze von Deployments und Dashboards, Timeouts und Idempotenz bei den Aufrufen an Zahlungen sowie Schemaänderungen, die weiterhin Abstimmung brauchen. Der Schritt ist bewusst bescheiden.
Servicebasierte Architektur wird oft mit der älteren serviceorientierten Architektur verwechselt, kurz SOA. Deren Kernidee war vernünftig: Geschäftsfähigkeiten als Services mit expliziten Verträgen bereitstellen. Doch die meisten Unternehmen bauten ihre Services in technischen Schichten auf. Oben beschreiben Business Services Prozesse, etwa eine Bestellung aufgeben oder ein Konto eröffnen. Im Zentrum saß ein Enterprise Service Bus, kurz ESB. Er leitete Nachrichten weiter, wandelte sie zwischen Formaten um und führte über eine Orchestrierungs-Engine die Geschäftsprozesse selbst aus. Darunter sollten gemeinsame Enterprise Services, etwa für Kunden und Preise, überall wiederverwendet werden, und sie kapselten ihrerseits bestehende Systeme. Und jede Nachricht wurde in ein kanonisches Datenmodell und aus ihm übersetzt: eine einzige unternehmensweite Definition jeder Geschäftsentität.
Viele SOA-Programme enttäuschten. Erstens erzeugte Wiederverwendung Kopplung. Ein gemeinsamer Kundenservice, den vierzig Anwendungen nutzten, konnte sich nicht ändern, ohne dass vierzig Consumer zustimmten. Zweitens wurde der Bus zum Engpass. Fast jede geschäftliche Änderung brauchte das eine Team, dem er gehörte, und er wurde zum Single Point of Failure. Drittens war das kanonische Modell zu groß. Eine Definition von Kunde, die Vertrieb, Abrechnung, Support und Logistik zufriedenstellt, ist entweder riesig oder für die meisten von ihnen falsch. Und die Webservice-Standards waren komplex, mit teuren Werkzeugen. Microservices behalten explizite Verträge bei, kehren aber die meisten dieser Entscheidungen um: Smart Endpoints and Dumb Pipes, mit der gesamten Logik in den Services und Daten, die jeweils einem Service gehören.
Wann ist servicebasierte Architektur also die richtige Wahl? Wenn das System wenige klare Geschäftsdomänen hat und zwei bis vielleicht acht Teams unabhängig ausliefern müssen. Wenn die meisten Abläufe innerhalb einer Domäne bleiben und starke Konsistenz innerhalb einer Domäne wertvoll ist. Sie ist außerdem ein ausgezeichneter Schritt aus einem Monolithen heraus: weit weniger riskant als der Sprung zu fünfzig Microservices und oft gut genug, um dort aufzuhören. Planen Sie, darüber hinauszugehen, wenn Teile sehr unterschiedliche Skalierung brauchen, wenn die gemeinsame Datenbank Schreibvorgänge begrenzt oder wenn sich Services für gewöhnliche Anfragen ständig gegenseitig aufrufen. Das ist ein Zeichen dafür, dass die Grenzen falsch sind.
Der vollständige Abschnitt vergleicht servicebasierte Architektur, SOA und Microservices direkt miteinander. Als Nächstes, in Abschnitt sechs Punkt drei, geht es um Microservices. Bis gleich.
Was Sie wissen müssen
- Servicebasierte Architektur (so benannt von Richards und Ford) teilt ein System in wenige separat deployte, grobgranulare Domain Services auf, typischerweise 4 bis 12, die sich meist eine Datenbank teilen und oft hinter einer API-Schicht liegen.
- Weil die meisten Abläufe innerhalb eines Domain Service bleiben, können sie lokale ACID-Transaktionen nutzen, und Services rufen sich selten gegenseitig auf, was synchrone Ketten kurz hält.
- Eine gemeinsame Datenbank koppelt Schemaänderungen und bindet die Services zu einem Quantum zusammen; Schemas pro Service, kleine Entity-Bibliotheken pro Domäne und, wo gerechtfertigt, getrennte Datenbanken verringern diese Kopplung.
- Die klassische, orchestrierungsgetriebene SOA ordnete Services in technischen Schichten um einen Enterprise Service Bus an, mit einem kanonischen Datenmodell und WS-*-Standards, und zielte auf unternehmensweite Wiederverwendung.
- SOA enttäuschte, weil Wiederverwendung Kopplung erzeugte, der Bus zum Engpass in der Hand eines einzigen Teams wurde, kanonische Modelle niemandem passten und die Standards schwerfällig waren.
- Microservices behalten explizite Serviceverträge bei, legen die Logik aber in die Services (Smart Endpoints, Dumb Pipes), organisieren sich nach Geschäftsfähigkeiten und geben jedem Service eigene Daten.
- Servicebasierte Architektur ist ein pragmatischer Mittelweg für wenige Domänen und Teams und ein risikoarmer Schritt aus einem Monolithen heraus.
Zwischen Monolith und Microservices
Ein Großteil der Diskussion in der Branche stellt eine Wahl zwischen einem Monolithen und vielen Microservices dar. In der Praxis liegt ein großer Teil realer Systeme dazwischen: eine Handvoll separat deployter Services, die jeweils einen ganzen Geschäftsbereich abdecken und sich oft noch eine Datenbank teilen. Mark Richards und Neal Ford haben diesen Stil in Fundamentals of Software Architecture servicebasierte Architektur genannt und halten ihn für einen der pragmatischsten verteilten Stile überhaupt. Dieser Abschnitt beschreibt ihn, grenzt ihn von der älteren serviceorientierten Architektur (SOA) ab, mit der er oft verwechselt wird, und zeigt, worin sich Microservices von beiden unterscheiden.
Servicebasierte Architektur: die Topologie
Ein servicebasiertes System hat drei Teile. Eine oder mehrere Benutzeroberflächen rufen eine Reihe separat deployter Domain Services auf, die jeweils einen großen, zusammenhängenden Geschäftsbereich wie Bestellungen oder Zahlungen abdecken. Richards und Ford beobachten, dass solche Systeme meist zwischen 4 und 12 Domain Services haben, im Durchschnitt etwa 7. Die Services teilen sich meist eine Datenbank, und eine optionale API-Schicht (ein Reverse Proxy oder Gateway) kann zwischen den Benutzeroberflächen und den Services liegen und Routing, Authentifizierung und Rate Limiting übernehmen.
Jeder Domain Service ist grobgranular: Er enthält alles, was seine Domäne braucht, von der API über die Geschäftslogik bis zum Datenzugriff, und ist intern wie ein kleiner Monolith aufgebaut, oft in Schichten oder Modulen (Kapitel 5). Ein Service wird typischerweise als einige Instanzen hinter einem Load Balancer deployt.
Daraus folgen zwei Konsequenzen. Erstens laufen die meisten Geschäftsabläufe vollständig innerhalb eines Service und können daher eine gewöhnliche lokale Datenbanktransaktion mit vollen ACID-Garantien nutzen (Kapitel 0). Zweitens müssen sich Domain Services selten gegenseitig aufrufen: Eine Anfrage von der Benutzeroberfläche geht an den einen Service, dem die Domäne gehört. Das hält synchrone Ketten kurz, was aus den in Abschnitt 6.1 berechneten Gründen wichtig ist.
Die gemeinsame Datenbank und wie man sie zähmt
Eine gemeinsame Datenbank macht servicebasierte Architektur günstig und einfach: keine Datensynchronisation zwischen Services, keine Eventual Consistency, Reporting mit gewöhnlichem SQL. Sie ist zugleich ihre Hauptschwäche. Lesen und schreiben alle Services dieselben Tabellen, kann eine Änderung an den Spalten einer Tabelle mehrere Services kaputt machen, die dann alle gemeinsam getestet und neu deployt werden müssen. Die Definition aus Kapitel 5 gilt: Services, die sich eine Datenbank teilen, sind zu einem Architekturquantum verbunden, sie teilen also ein Verfügbarkeitsniveau und einen Rhythmus für Schema-Releases.
In der Praxis gibt es drei Techniken, um die Kopplung zu verringern. Die erste ist logische Partitionierung: Jeder Service erhält sein eigenes Schema (oder seinen eigenen Satz von Tabellen) und darf die der anderen nicht anfassen, durchgesetzt sowohl durch Datenbankberechtigungen als auch durch Konvention. Die zweite besteht darin, die Entity-Klassen der gemeinsamen Datenbank in kleinen Bibliotheken pro Domäne statt in einer großen gemeinsamen Bibliothek zu halten, sodass eine Änderung an Restauranttabellen nur die Services betrifft, die sie nutzen. Die dritte besteht darin, einem Service eine eigene Datenbank zu geben, wenn er einen triftigen Grund hat, etwa den Sicherheitsumfang, ein ganz anderes Lastmuster oder eine andere Art von Datenspeicher. Teams, die diese Techniken konsequent anwenden, stellen fest, dass ein späterer Wechsel zu getrennten Datenbanken, falls er je nötig wird, viel leichter fällt.
Die Essenslieferplattform als fünf Domain Services
Ausgearbeitetes Beispiel
Ausgearbeitetes Beispiel: die Essenslieferplattform als fünf Domain Services
Ein Essenslieferunternehmen ist von einem Team auf fünf gewachsen, etwa 35 Entwicklerinnen und Entwickler. Sein Django-Monolith ist gut modularisiert, aber Releases sind zur Warteschlange geworden, und ein Fehler im Kurier-Tracking hat im letzten Quartal zweimal den Checkout lahmgelegt. Die Architektin schlägt eine servicebasierte Architektur mit fünf Domain Services vor, einem pro bestehendem Modul und Team.
| Bestellung | Warenkorb, Checkout, Lebenszyklus und Status von Bestellungen. Besitzt das Schema ordering. Zu Essenszeiten stark ausgelastet; läuft mit 6 bis 20 Instanzen. |
|---|---|
| Restaurant | Speisekarten, Preise, Öffnungszeiten, Onboarding von Restaurants. Leselastig; Speisekarten werden in der API-Schicht gecacht. Läuft mit 3 Instanzen. |
| Zustellung | Kurierdisposition, Routenschätzungen, Live-Tracking. Erhält alle paar Sekunden Standort-Updates von jedem aktiven Kurier und wird daher getrennt von allem anderen skaliert. |
| Zahlungen | Kartenautorisierung über den Zahlungsanbieter, Erstattungen, Auszahlungen an Restaurants und Kuriere. Hat eine eigene Datenbank, damit der Umfang der PCI-DSS-Prüfung ein kleiner Service ist statt der ganzen Plattform. |
| Kunde | Konten, Adressen, Support-Tickets, Bewertungen. Geringe Last, hält aber die meisten personenbezogenen Daten, daher sind Zugriffs- und Aufbewahrungsregeln hier konzentriert. |
| Wie ein Ablauf läuft | Bestellen läuft innerhalb von Bestellung in einer lokalen Transaktion (Bestellung anlegen, den Zeitslot des Restaurants reservieren) und macht dann einen Aufruf an Zahlungen. Restaurant und Lieferung erfahren von der Bestellung über eine Nachricht, nicht über eine Kette von Aufrufen. |
| Was geteilt wird | Ein PostgreSQL-Server mit einem Schema pro Service. Jeder Service darf nur sein eigenes Schema lesen und schreiben; einige schreibgeschützte Views (zum Beispiel Restaurantnamen) werden für die anderen veröffentlicht. |
| Was es bringt | Fünf Deployment-Pipelines statt einer; ein Fehler im Tracking stoppt den Checkout nicht mehr; Zahlungen lassen sich allein auditieren; jedes Team liefert aus, wenn es so weit ist. |
| Was es kostet | Fünf deploybare Einheiten und Dashboards statt einer; Netzwerkaufrufe zwischen Bestellung und Zahlungen, die Timeouts und Idempotenz brauchen; Schemaänderungen müssen weiterhin über den gemeinsamen Datenbankserver koordiniert werden. |
Der Schritt ist bewusst bescheiden. Er führt von einem Quantum zu ungefähr zweien (Zahlungen mit eigenen Daten und die vier Services, die sich die Datenbank teilen), und er gibt jedem Team sein eigenes Release, was der Hauptschmerz war.
Wächst der Standort-Stream von Lieferung später über die gemeinsame Datenbank hinaus, kann dieser eine Service einen eigenen Speicher erhalten und weiter aufgeteilt werden; der Rest kann bleiben, wie er ist.
Die Architektin hält die Grenzregeln als Architekturtests fest: Kein Service darf das Schema eines anderen abfragen, und Services dürfen sich nur über veröffentlichte APIs gegenseitig aufrufen.
Klassische serviceorientierte Architektur
Serviceorientierte Architektur ist älter und breiter angelegt. Der Begriff kam 1996 durch einen Gartner-Bericht von Roy Schulte und Yefim Natis in die Branche, und ab den frühen 2000er-Jahren wurde sie zum vorherrschenden Modell der Unternehmensintegration. Ihre Kernidee war vernünftig: Geschäftsfähigkeiten als Services mit expliziten, technologieneutralen Verträgen bereitstellen, sodass Anwendungen in einer großen Organisation daraus zusammengesetzt werden können, statt neu gebaut oder Punkt zu Punkt integriert zu werden.
Was die meisten Unternehmen tatsächlich bauten, war jedoch das, was Richards und Ford orchestrierungsgetriebene SOA nennen. Services wurden in technischen Schichten angeordnet: Business Services, die Prozesse beschreiben (Bestellung aufgeben, Konto eröffnen), gemeinsame Enterprise Services, die wiederverwendbare Fähigkeiten bereitstellen (Kunde, Preisgestaltung, Rechnung), sowie Application und Infrastructure Services, die bestehende Systeme und technische Anliegen kapseln. Im Zentrum saß ein Enterprise Service Bus (ESB): Middleware, die Nachrichten weiterleitete, zwischen Formaten umwandelte, zwischen Protokollen vermittelte und über eine Orchestrierungs-Engine die Geschäftsprozesse selbst ausführte.
Zwei weitere Ideen vervollständigten das Bild. Ein kanonisches Datenmodell definierte eine unternehmensweite Darstellung jeder Geschäftsentität (ein Customer, ein Order), und jede Nachricht wurde im Bus in diese Darstellung und aus ihr übersetzt. Und eine Familie von Webservice-Standards, meist WS-* genannt, legte fest, wie Services einander beschreiben und aufrufen: SOAP für Nachrichten, WSDL für Schnittstellenbeschreibungen, UDDI für Registries, WS-Security, WS-ReliableMessaging und WS-AtomicTransaction für Qualitäten und WS-BPEL (Version 2.0, 2007 von OASIS verabschiedet) für ausführbare Prozessdefinitionen.
Orchestrierungsgetriebene SOA
Warum die klassische SOA in Ungnade fiel
Ende der 2000er-Jahre hatten viele SOA-Programme enttäuscht. Anne Thomas Manes von der Burton Group fasste die Stimmung im Januar 2009 in einem viel gelesenen Beitrag mit dem Titel SOA is Dead; Long Live Services zusammen: Das Etikett war toxisch geworden, aber die Idee der Services überlebte. Die Gründe sind wissenswert, denn jeder ist eine Falle, in die moderne Architekturen erneut tappen können.
Wiederverwendung erzeugte Kopplung. Ein gemeinsamer Enterprise-Customer-Service, den vierzig Anwendungen nutzten, konnte sich nicht ändern, ohne dass vierzig Consumer zustimmten; die Wiederverwendung, das Hauptziel, machte jede Änderung zur Verhandlung. Der Bus wurde zum Engpass. Routing, Transformation und Prozesslogik in einen zentralen ESB zu legen, der meist einem einzigen Integrationsteam gehörte, bedeutete, dass fast jede geschäftliche Änderung dieses Team brauchte, und der Bus wurde zu einem Single Point of Failure und der Verzögerung. Das kanonische Modell war zu groß. Eine Definition von Customer, die Vertrieb, Abrechnung, Support und Logistik zufriedenstellt, ist entweder riesig oder für die meisten von ihnen falsch; die Bounded Contexts aus Kapitel 5 erklären, warum ein Begriff in verschiedenen Teilen eines Unternehmens berechtigterweise Verschiedenes bedeutet. Die Standards waren schwerfällig. WS-*-Spezifikationen waren komplex, die Werkzeuge teuer, und verteilte Transaktionen über Services hinweg erwiesen sich als fragil. Technische Partitionierung bedeutete, dass ein einfaches Feature mehrere Schichten von Services durchquerte, die verschiedenen Gruppen gehörten.
Die bleibenden Lehren sind die, auf denen Microservices aufgebaut wurden: explizite Serviceverträge, Services, die denen gehören, die sie bauen, Logik in den Services statt in der Middleware und Daten, die einem Service gehören, statt im ganzen Unternehmen geteilt zu werden.
Worin sich Microservices unterscheiden
Microservices, die im nächsten Abschnitt ausführlich behandelt werden, behalten die SOA-Idee von Services mit expliziten Verträgen bei und kehren die meisten ihrer Umsetzungsentscheidungen um. James Lewis und Martin Fowler fassten eine dieser Umkehrungen als Smart Endpoints and Dumb Pipes zusammen: Das Netzwerk transportiert nur Nachrichten, und die gesamte Logik liegt in den Services. Services sind um Geschäftsfähigkeiten statt um technische Schichten organisiert, Wiederverwendung ist der Unabhängigkeit bewusst nachgeordnet, jeder Service besitzt seine Daten, und Governance ist dezentralisiert.
Verglichen mit servicebasierter Architektur sind Microservices feingranularer, weit zahlreicher und bestehen auf getrennten Daten. Das bringt mehr Unabhängigkeit, gezieltere Skalierung und mehr Fehlerisolation und kostet viel mehr an Betrieb, Konsistenz und Koordination. Servicebasierte Architektur lässt sich als der Punkt im Spektrum sehen, an dem der Großteil des Nutzens für Deployment und Teams zu einem Bruchteil der Kosten eintritt.
Servicebasierte Architektur, klassische SOA und Microservices im Vergleich
| Aspekt | Servicebasiert | Klassische (orchestrierungsgetriebene) SOA | Microservices |
|---|---|---|---|
| Hauptziel | Pragmatische Modularität und unabhängiges Deployment weniger Domänenbereiche | Unternehmensweite Wiederverwendung gemeinsamer Services | Unabhängige Änderung und unabhängiges Deployment durch viele autonome Teams |
| Partitionierung | Fachlich: ein Service pro großem Geschäftsbereich | Technisch: Business-, Enterprise-, Application- und Infrastructure-Schicht | Fachlich: ein Service pro Bounded Context oder kleiner |
| Typische Anzahl | Etwa 4 bis 12 pro System | Dutzende bis Hunderte im ganzen Unternehmen | Zehn bis Hunderte pro System |
| Granularität | Grob: eine ganze Domäne, zum Beispiel alles rund um Bestellungen | Gemischt; gemeinsame Enterprise Services sind oft feingranular | Fein bis mittel: eine kohäsive Fähigkeit |
| Daten | Oft eine gemeinsame Datenbank, idealerweise nach Schemas partitioniert | Gemeinsame Systems of Record hinter Enterprise Services | Jeder Service besitzt seine Daten; keine gemeinsamen Tabellen |
| Kommunikation | Meist von der Benutzeroberfläche zu einem Service; wenige Aufrufe zwischen Services | Über den Enterprise Service Bus, meist SOAP oder XML-Messaging | Leichtgewichtiges HTTP, gRPC oder Messaging; Smart Endpoints, Dumb Pipes |
| Wo die Logik liegt | In den Domain Services | Ein Großteil im Bus: Routing, Transformation, Orchestrierung | In den Services; das Netzwerk transportiert nur |
| Transaktionen | Lokale ACID-Transaktionen innerhalb eines Domain Service | Versuche mit verteilten Transaktionen (WS-AtomicTransaction, XA) | Keine verteilten Transaktionen; Sagas und Eventual Consistency |
| Governance | Leicht; ein Architekturteam genügt | Zentral und schwerfällig: kanonisches Modell, Service Registry, Standardgremium | Dezentralisiert; gemeinsame Plattform und Paved Roads |
| Betriebskosten | Moderat | Hoch, plus teure Middleware-Lizenzen | Hoch: viele deploybare Einheiten, Pipelines und Bereitschaftspläne |
Merkmale der servicebasierten Architektur
| Merkmal | Bewertung | Grund |
|---|---|---|
| Deploybarkeit | Mittel bis hoch | Jeder Domain Service wird für sich deployt, sodass eine Änderung an Speisekarten kein erneutes Deployment der Zahlungen auslöst; eine gemeinsame Schemaänderung braucht weiterhin Abstimmung. |
| Fehlertoleranz | Mittel bis hoch | Ein Absturz im Lieferservice lässt Bestellungen und Zahlungen weiterlaufen; eine gemeinsame Datenbank ist weiterhin ein gemeinsamer Ausfallpunkt. |
| Skalierbarkeit | Mittel | Services skalieren getrennt, aber jeder ist grob, und die gemeinsame Datenbank begrenzt, wie weit sich Schreibvorgänge skalieren lassen. |
| Elastizität | Niedrig bis mittel | Große Services starten langsam und skalieren in großen Schritten, sodass plötzliche Lastspitzen weniger elegant abgefangen werden als mit kleinen Services. |
| Datenkonsistenz | Hoch | Die meisten Geschäftsabläufe bleiben innerhalb eines Service, wo eine gewöhnliche Datenbanktransaktion die Daten konsistent hält. |
| Einfachheit | Mittel | Weit weniger bewegliche Teile als Microservices; dennoch ein verteiltes System mit Netzwerkaufrufen, Deployment-Pipelines und Monitoring pro Service. |
| Gesamtkosten | Mittel (moderat) | Eine Handvoll Services und eine Datenbank sind günstig im Betrieb verglichen mit Dutzenden Services und Datenbanken. |
| Testbarkeit | Mittel bis hoch | Jeder Service hat einen kleineren Umfang als der Monolith und kann für sich gegen sein Schema getestet werden. |
| Evolvierbarkeit | Mittel | Fachliche Partitionierung hält typische Änderungen innerhalb eines Service, aber die gemeinsame Datenbank koppelt die Schemaevolution. |
Wann servicebasierte Architektur der pragmatische Mittelweg ist
Wählen Sie sie, wenn das System wenige klare Geschäftsdomänen hat, wenn zwei bis vielleicht acht Teams unabhängig ausliefern müssen, wenn die meisten Abläufe natürlicherweise innerhalb einer Domäne bleiben und wenn starke Konsistenz innerhalb einer Domäne wertvoll ist. Sie ist außerdem ein ausgezeichneter Migrationsschritt aus einem Monolithen heraus: Einen gut modularisierten Monolithen in eine Handvoll Domain Services zu zerlegen ist weit weniger riskant als der Sprung zu fünfzig Microservices, und das Ergebnis ist oft gut genug, um dort aufzuhören.
Vermeiden Sie sie oder planen Sie, über sie hinauszugehen, wenn Teile einer Domäne sehr unterschiedliche Skalierbarkeit oder Verfügbarkeit brauchen (sie gehören in getrennte Quanten), wenn Dutzende Teams Autonomie brauchen, wenn die gemeinsame Datenbank zum Engpass für Schreibvorgänge geworden ist oder wenn sich die Domain Services ständig gegenseitig aufrufen, um gewöhnliche Anfragen zu erledigen, was ein Zeichen dafür ist, dass die Grenzen falsch sind.
Prüfen Sie Ihr Verständnis
Warum können die meisten Abläufe in einer servicebasierten Architektur eine gewöhnliche Datenbanktransaktion nutzen?
Weil jeder Domain Service einen ganzen Geschäftsbereich abdeckt und der Ablauf meist innerhalb dieses Service bleibt, sodass er nur Daten im eigenen Schema des Service in einer Datenbank berührt.
Was machte den Enterprise Service Bus in vielen SOA-Programmen zum Engpass?
Routing, Transformation und Prozesslogik lagen im Bus, der typischerweise einem zentralen Team gehörte; daher brauchten die meisten geschäftlichen Änderungen dieses Team, und der Bus war ein gemeinsamer Ausfallpunkt.
Nennen Sie zwei Techniken, die die Kopplung durch eine gemeinsame Datenbank verringern.
Jedem Service ein eigenes Schema geben und den Zugriff auf andere verbieten (durch Berechtigungen durchgesetzt) und Entity-Klassen in kleine Bibliotheken pro Domäne aufteilen; außerdem einem Service, wo gerechtfertigt, eine eigene Datenbank geben.
Was kehrt „Smart Endpoints and Dumb Pipes“ gegenüber der klassischen SOA um?
Es verlagert die Logik aus der Middleware (dem ESB) in die Services, und das Netzwerk transportiert nur noch Nachrichten.
Quellen und weiterführende Literatur
- James Lewis and Martin Fowler: Microservices (2014), on smart endpoints and dumb pipes
- OASIS: Reference Model for Service Oriented Architecture 1.0
- W3C: Web Services Architecture (Working Group Note)
- OASIS: Web Services Business Process Execution Language Version 2.0
- Enterprise Integration Patterns: messaging patterns catalogue
Haben Sie eine Frage zu diesem Abschnitt? ArchitectBot, der KI-Lernassistent des Kurses, antwortet zuerst aus dem Kurs.
Fragen: „Wir haben einen modularen Monolithen und vier Teams. Sollten wir zu einer servicebasierten Architektur wechseln oder direkt zu Microservices, und was sollten wir mit der gemeinsamen Datenbank tun?“