Beispiel C: Trainingsplattform in der Luftfahrt
- Problem: Komplexes Kurs- und Berechtigungsmodell, umfangreiche Audit-Trails, On-Prem- oder private Cloud-Deployment; lange Lebensdauer.
- Architektur:
- Modulare Monolithen mit klaren Modulen: Identity & Roles, Curriculum, Simulator Sessions, Compliance, Reporting.
- Event-Log intern für Audit, exportierbar; Berichte generiert asynchron, aber in-prozess getriggert.
- API-Layer stabil, aber nach außen nur ein Endpunkt (Gateway) – geringe Angriffsfläche, einfache Härtung.
- Warum Monolith? Compliance-getriebene Konsistenz, Planbarkeit von Releases, minimierte Betriebsvariabilität.
5) Operative Vorteile im On-Prem-Setup
- Ein Artefakt, eine Lieferkette: Ein signiertes Paket mit SBOM, reproduzierbar gebaut. Weniger Angriffspunkte, einfachere Audits.
- Rollback und Datenmigrationen: Migrationsskripte transaktional, idempotent; die Kopplung an ein Artefakt reduziert Komplexität bei Vor-Ort-Rollbacks erheblich.
- Observability ohne Service-Zoo: Interne Komponenten emittieren Traces mit Komponentenschlüsseln, Logs strukturiert mit Korrelationen über Event-IDs. Ein Agent, ein Ziel.
- Netzwerk-Härtung: Keine Service Discovery, kein Service Mesh, keine dynamischen Sidecars, die in air-gapped Netzen ohnehin schwer zu betreiben sind. TLS innerhalb eines Prozesses irrelevant; zwischen wenigen Prozessen mTLS mit eigener PKI machbar.
- Ressourcenökonomie: Ein Prozess kann Speicher- und Objektpools effizient teilen. Kein serielles (De-)Serialisieren zwischen Services, keine gRPC-Overheads für Intra-Domain-Kommunikation.
6) Leistungsprofil und Skalierung eines Monolithen
Skalierung ist nicht exklusiv ein Microservice-Feature. Typische Muster:
- Vertikale Skalierung: Realtime-Pfade in C++ mit lock-armen Queues, NUMA-Awareness, Pinning. Kritische Hot Paths sind im Monolith leichter zu profilieren und in einem Adressraum zu optimieren.
- Horizontale Skalierung: Mehrere Instanzen des Monolithen hinter einem simplen TCP/HTTP-Loadbalancer. Externen Zustand in einer robusten Datenbank oder einem dedizierten State Store (z. B. Redis) halten. Session-Management entkoppeln oder Sticky Sessions einsetzen.
- Interne Parallelisierung: Worker-Pools pro Modul, Backpressure über interne Queues. Asynchronität ist nicht an Netzgrenzen gebunden.
- Read/Write-Skalierung: CQRS intern anwenden – getrennte Lesemodelle/Materialized Views für Dashboards, ohne das Domänenmodell aufzublähen.
- Batch-Heavy Workloads: Dedizierte Worker-Prozesse (innerhalb desselben Deployments) für ETL/Analytik; Start/Stop steuerbar, Ressourcen limitiert, ohne separate Deploy-Pipelines.
Wann Microservices in puncto Skalierung dennoch gewinnen:
- Wenn einzelne Domänenkomponenten echt unterschiedliche Lastcharakteristika und Lebenszyklen haben, die mit separatem Deployment erheblich günstiger zu betreiben sind (z. B. stark variable, extern konsumierte Public API vs. stabile interne Planung).
- Wenn unabhängige Teams mit klaren, stabilen Boundaries autonom liefern müssen.
7) Grenzen des Monolithen und Exit-Strategie ohne Big-Bang
Symptome, dass eine Extraktion sinnvoll wird:
- Ein Modul hat andere Verfügbarkeits- und Skalierungsziele als der Rest (z. B. extern exponierte API mit spiky Traffic).
- Sicherheitsgründe erfordern Isolation (z. B. Ausführung untrusted Drittanbieterlogik, regulatorisch getrennte Datenbereiche).
- Release-Kadenz divergiert massiv (z. B. monatliche Compliance-Releases vs. tägliche Modellupdates).
Migrationspfad:
- Strangler-Pattern: Zu extrahierende Capability durch einen internen Adapter kapseln. Dann die Implementierung über eine Remote-Schnittstelle ersetzen, ohne die restliche Codebasis zu berühren.
- Contract-First: Klare, versionierte APIs (idealerweise coarse-grained), keine Chatty Patterns. Kompatibilitätsfenster definieren.
- Datenabkopplung: Database-per-service für den extrahierten Teil. Datenfluss über Events (Outbox-Pattern) oder wohldefinierte Sync-Prozesse; Idempotenz sicherstellen.
- Inkrementelle Teilauslagerung: Zuerst nicht-kritische Pfade, Telemetrie und Rollback-Pfade stehen lassen, bevor Kerntransaktionen verteilt werden.
8) Anti-Patterns und realistische Alternativen
Zu vermeiden:
- Microservice pro Feature: Führt zu N Services für N Features, aber mit hoher Kopplung über geteilte Schemas und synchrone Kaskaden – ein verteilter Monolith mit schlechterem Latenzprofil.
- Shared Database über Services: Unterminiert Service-Grenzen, macht Migrationsplanung zur Hölle.
- Interne Remote Calls für triviale Domäneninteraktionen: Wenn 95% der Interaktion innerhalb eines Teams liegt, ist das Netzwerk nur Ballast.
- Service Mesh in air-gapped Umgebungen: Komplexität und Operabilität kollidieren mit statischen Netzen und schmalen Betriebs-Teams. mTLS und feste Endpunkte sind oft die praktikablere Wahl.
Realistische Alternativen:
- Grobgranulare Service-Aufteilung: 2–5 Services mit starken Boundaries (z. B. “Operations Core”, “Public API”, “ML Inference Farm”, “Reporting”), statt 20+ Microlithen.
- File- oder Message-basierte Übergaben für schwere Artefakte: Für große Bild-/Sensordaten sind robuste File-Drops oder objektbasierte Stores mit sidecar-freier Auth oft betriebssicherer als Chatty RPC.
- IPC statt Netzwerk, wo Isolation nötig ist: Subprozesse mit klaren Protokollen (z. B. Cap’n Proto, FlatBuffers über Shared Memory) liefern Stabilität ohne Netzwerklast.
9) API- und Datenvertragsdisziplin auch im Monolith
Nur weil intern alles in einem Prozess läuft, heißt das nicht, dass Schnittstellendisziplin egal ist:
- Versionierte interne Interfaces: Jedes Modul veröffentlicht Ports mit klaren Semantiken, semantischer Versionierung und Deprecation-Plänen.
- Migrationstechniken: Database-Migrationen vorwärts- und rückwärtskompatibel (expand-contract). Feature Flags für neue Felder/Verhalten.
- Antikorruptionsschichten: Für Legacy-Teile, die noch nicht refaktoriert sind, klare Adapter, die die Unerfreulichkeiten kaschieren.
10) Sicherheit und Lieferkette
- Sprache und Isolation: Realtime-Pfade in C++ sind legitim, aber memory safety erfordert Disziplin (Sanitizer in CI, fuzzing). Für untrusted Plugins oder komplexe Parser lohnt Rust oder Prozessisolation.
- Signierte Artefakte, reproduzierbare Builds: Ein Artefakt, eine Signaturkette, SBOM. In zukunftsfesten Organisationen ist das gelebte Praxis, nicht Poster an der Wand.
- Secrets und Zertifikate: Eigene PKI, kurzlebige Zertifikate, Rotation über das gleiche Installationssystem. Kein externer Geheimnisspeicher im Internet, wenn air-gapped.
- Least privilege: Auch im Monolithen sind Subprozesse mit weniger Rechten wertvoll (z. B. Inferenz-Worker ohne Schreibrechte auf zentrale DB).
11) Cloud-native vs. On-Premise: Muster für regulierte Branchen