Skip to content

Die Evolution vom Monolith zu Microservices

Einleitung

Keine Architektur ist „die beste" — es gibt nur die Architektur, die am besten zur aktuellen Phase passt. Der Übergang vom Monolithen zu Microservices ist kein Sprung, der in einem Schritt vollzogen wird, sondern ein schrittweiser Evolutionsprozess, der mit dem Wachstum des Geschäftsumfangs und der Teamgröße einhergeht. Eine zu frühe Aufspaltung in Microservices ist genauso gefährlich wie eine zu späte.

Was werden Sie in diesem Artikel lernen?

Nach Abschluss dieses Kapitels werden Sie Folgendes beherrschen:

  • Evolutionärer Pfad: Vier Phasen vom Monolithen zu Microservices verstehen
  • Zeitpunkt der Aufspaltung: Wissen, wann aufgespalten werden sollte und wann nicht
  • Aufspaltungsstrategien: Methodik der domänenbasierten Aufspaltung beherrschen
  • Kommunikationsmuster: Synchron und asynchrone Kommunikation zwischen Services kennenlernen
  • Datenaufspaltung: Herausforderungen und Lösungen der Datenbankaufspaltung verstehen
KapitelInhaltKernkonzepte
Kapitel 1ArchitekturevolutionMonolith → Modularer Monolith → SOA → Microservices
Kapitel 2Zeitpunkt und Prinzipien der AufspaltungConway's Law, Team-Autonomie
Kapitel 3AufspaltungsstrategienDDD Bounded Context, Strangler Fig Pattern
Kapitel 4Service-KommunikationREST, gRPC, Nachrichtenwarteschlangen
Kapitel 5DatenaufspaltungDatenbankaufspaltung, Datensynchronisation

1. Architekturevolution

Die Architekturevolution wird nicht von der Technologie, sondern von der Organisationsgröße angetrieben. Wenn ein Team von 5 auf 500 Personen wächst, sinkt die Zusammenarbeitseffizienz in einer monolithischen Architektur drastisch.

PhaseArchitekturTeamgrößeMerkmale
StartphaseMonolithische Anwendung1–10 PersonenGesamter Code in einem Projekt, einfaches Deployment
WachstumsphaseModularer Monolith10–50 PersonenCode nach Modulen gegliedert, aber weiterhin gemeinsam bereitgestellt
ExpansionsphaseSOA (Serviceorientiert)50–200 PersonenGrobe Services nach Geschäftsbereichen aufgeteilt
SkalierungsphaseMicroservices200+ PersonenFeingranulare Services, jedes Team entwickelt und deployt unabhängig
Architecture Evolution Path
Click each stage to inspect its architecture characteristics
1
Monolithic architecture
2
Modular monolith
3
Service-oriented architecture
4
Microservices architecture
Monolithic architecture
All features are packaged in one application and share one database. It is simple and suitable for early rapid iteration.
User module
Order module
Payment module
Product module
Monolith app (one process)
MySQL
Suitable scale:Team < 10 people, DAU < 100k
Core challenge:Code is tightly coupled; a bug in one module may bring down the whole system

Conway's Law

„Organisationen, die Systeme entwerfen, produzieren Architekturen, die ihrer Kommunikationsstruktur entsprechen." — Melvin Conway

Einfach gesagt: 3 Teams, die ein System bauen, werden am Ende 3 Services haben. Die Essenz der Architekturaufspaltung ist die Organisationsaufspaltung.

Inverse Conway's Law: Da die Organisationsstruktur die Systemarchitektur bestimmt, sollte man zuerst die Organisationsstruktur anpassen, um die gewünschte Architektur zu erhalten. Wenn Sie beispielsweise einen unabhängigen Zahlungsservice aufspalten möchten, bilden Sie zuerst ein unabhängiges Zahlungsteam. Bei vielen Unternehmen scheitert die Microservice-Aufspaltung nicht aus technischen Gründen, sondern weil die Organisation sich nicht angepasst hat.


2. Wann sollte man zu Microservices aufspalten?

Nicht jedes System benötigt Microservices. Eine zu frühe Aufspaltung bringt unnötige Komplexität mit sich.

SignalBeschreibungEmpfehlung
Häufige Deployment-KonflikteMehrere Teams arbeiten an derselben Codebasis mit häufigen KonfliktenAufspaltung erwägen
Ein Modul benötigt unabhängige SkalierungDas Suchmodul benötigt 10x mehr Ressourcen als andere ModuleAufspaltung erwägen
Differenzierte Technologie-StacksKI-Modul in Python, Hauptseite in JavaAufspaltung erwägen
Team < 10 PersonenGeringe Kommunikationskosten, Monolith reicht ausNicht aufspalten
Geschäft in der ExplorationsphaseHäufig wechselnde Anforderungen, unklare GrenzenNicht aufspalten
Keine DevOps-FähigkeitenKein CI/CD, Containerisierung oder Monitoring-SystemNicht aufspalten

3. Aufspaltungsstrategien

3.1 Domänenbasierte Aufspaltung (DDD Bounded Context)

Der Bounded Context (begrenzter Kontext) aus DDD (Domain-Driven Design) ist das beste Leitprinzip für die Aufspaltung von Microservices. Jeder Bounded Context entspricht einer unabhängigen Geschäftsdomäne mit eigenem Datenmodell und eigenen Geschäftsregeln.

Was ist ein Bounded Context? Dasselbe Wort hat in verschiedenen Geschäftsdomänen unterschiedliche Bedeutungen. Zum Beispiel bedeutet „Benutzer" in der Benutzerdomäne Registrierungsinformationen (Name, E-Mail), in der Bestellungsdomäne den Besteller (Lieferadresse, Zahlungsmethode) und in der Empfehlungsdomäne das Verhaltensprofil (Browserverlauf, Präferenz-Tags). Der Bounded Context zieht eine Grenze, innerhalb derer Begriffe und Modelle eine eindeutige und einheitliche Bedeutung haben.

┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│  Benutzer-   │  │  Bestellungs-│  │  Zahlungs-   │
│  domäne      │  │  domäne      │  │  domäne      │
│              │  │              │  │              │
│ User         │  │ Order        │  │ Payment      │
│ Profile      │  │ OrderItem    │  │ Refund       │
│ Address      │  │ Cart         │  │ Transaction  │
│              │  │              │  │              │
│ Benutzer-    │  │ Bestellungs- │  │ Zahlungs-    │
│ dienst       │  │ dienst       │  │ dienst       │
└──────┬───────┘  └──────┬───────┘  └──────┬───────┘
       │                  │                  │
       └──── API-Aufrufe / Ereigniskommunikation ────┘
Bounded ContextKernentitätenEntsprechender Service
BenutzerdomäneUser, Profile, AddressBenutzer-Service
ProduktdomäneProduct, Category, SKUProdukt-Service
BestellungsdomäneOrder, OrderItemBestellungs-Service
ZahlungsdomänePayment, RefundZahlungs-Service
LogistikdomäneShipment, TrackingLogistik-Service

3.2 Strangler Fig Pattern (Würgefeigen-Muster)

Den gesamten Monolithen nicht auf einmal neu schreiben, sondern wie eine Würgefeige schrittweise alte Module durch neue Services ersetzen:

  1. Neuen Service außerhalb des Monolithen erstellen
  2. Über eine Proxyschicht einen Teil des Datenverkehrs zum neuen Service routen
  3. Nach Validierung der Stabilität des neuen Services schrittweise mehr Verkehr migrieren
  4. Schließlich das alte Modul vollständig ersetzen

4. Service-Kommunikationsmuster

MethodeProtokollMerkmaleAnwendungsbereich
RESTHTTP/JSONEinfach, universell, gutes ÖkosystemExterne APIs, CRUD-Operationen
gRPCHTTP/2 + ProtobufHohe Leistung, starke TypisierungInterne hochfrequente Service-Aufrufe
NachrichtenwarteschlangeAMQP/KafkaAsynchrone Entkopplung, LastspitzenabflachungEreignisbenachrichtigungen, asynchrone Aufgaben
GraphQLHTTP/JSONClient-seitige bedarfsgerechte AbfragenBFF-Schicht, mobile Clients

Wahl zwischen synchron und asynchron

  • Sofortiges Ergebnis benötigt → Synchron (REST/gRPC)
  • Kein sofortiges Ergebnis benötigt → Asynchron (Nachrichtenwarteschlange)
  • Ein Ereignis löst mehrere Aktionen aus → Asynchron (Publish-Subscribe)

Faustregel: So viel Asynchronität wie möglich. Je länger die synchrone Aufrufkette, desto fragiler das System.


5. Datenaufspaltung: Der schwierigste Teil

Der schmerzhafteste Teil der Microservice-Aufspaltung ist nicht die Codeaufspaltung, sondern die Datenbankaufspaltung. Jeder Service sollte seine eigene Datenbank besitzen, was jedoch bedeutet, dass serviceübergreifende Abfragen schwierig werden.

HerausforderungBeschreibungLösung
Serviceübergreifende JOINsTabellen zweier Services können nicht direkt gejoint werdenAPI-Kompositionsabfragen, Datenredundanz
Verteilte TransaktionenDatenbankübergreifende Transaktionen können keine lokalen Transaktionen nutzenSaga, lokale Nachrichtentabelle
DatenkonsistenzDaten mehrerer Services können vorübergehend inkonsistent seinEventuale Konsistenz, ereignisgesteuert
DatenmigrationMigration von gemeinsam genutzter zu eigenständiger DatenbankDual-Write-Übergang, Datensynchronisationstools

Zusammenfassung

Der Übergang vom Monolithen zu Microservices ist ein schrittweiser Prozess, keine Revolution über Nacht.

Rückblick auf die wichtigsten Punkte dieses Kapitels:

  1. Evolutionärer Pfad: Monolith → Modularer Monolith → SOA → Microservices, jede Stufe hat einen klaren Treiber
  2. Zeitpunkt der Aufspaltung: Teamgröße, Deployment-Konflikte, Skalierungsanforderungen sind Signale für die Aufspaltung
  3. Aufspaltungsstrategien: DDD Bounded Context zur Leitplanke, Strangler Fig Pattern für schrittweise Migration
  4. Kommunikationswahl: So asynchron wie möglich, synchrone Aufrufketten so kurz wie möglich
  5. Datenaufspaltung: Am schwierigsten, aber am wichtigsten — die Akzeptanz der eventualen Konsistenz ist der entscheidende Denkansatz

Weiterführende Literatur