Der Monolith bremst die Auslieferung
Ein gewachsenes System lässt sich nur als Ganzes deployen, jede Änderung erfordert eine Regression über alles. Wir bestimmen die ersten tragfähigen Schnitte und den Weg dorthin.
ARCHITECTURE · 03 / 06
Architektur ist die Summe der Entscheidungen, die später teuer zu ändern sind: wo die Grenze zwischen zwei Komponenten verläuft, welche Daten zusammengehören, welcher Vertrag an einer Schnittstelle gilt. Wir treffen diese Entscheidungen explizit, halten sie mit Begründung und verworfenen Alternativen fest und leiten daraus einen Migrationsweg ab, der in kleinen Schritten produktiv geht. Statt eines Zielbilds auf Folien entsteht eine Struktur, die sich an Code, Datenmodell und Telemetrie überprüfen lässt.
Ausgangslage
Die häufigste Ursache für Änderungsangst ist nicht schlechter Code, sondern ein unklarer Schnitt. Fünf Module lesen dieselbe Tabelle direkt, jedes mit eigener Annahme über Nullbarkeit und erlaubte Statuswerte. Eine Spaltenumbenennung wird damit zum organisationsweiten Vorgang. Wer die Abhängigkeit nicht kennt, entdeckt sie erst beim Deployment – und baut anschließend eine weitere Sonderbehandlung ein, statt die Grenze endlich zu ziehen.
Der Gegenreflex ist Aufteilung um jeden Preis. Aus einem Monolithen werden zwanzig Dienste, die synchron über HTTP aufeinander warten und weiterhin dieselbe Datenbank beschreiben. Statt Entkopplung entsteht ein verteilter Monolith: dieselbe Kopplung, zusätzlich Netzlatenz, Teilausfälle und Konsistenzprobleme über Dienstgrenzen. Die Fehlersuche verteilt sich auf viele Logdateien, ohne dass jemand Tracing eingeführt hätte. Die Auslieferungsfrequenz sinkt, anstatt zu steigen.
Entscheidungen sind meist getroffen, aber nirgends festgehalten. Warum die Warteschlange auf einem eigenen Broker läuft und nicht auf PostgreSQL mit SKIP LOCKED, weiß eine Person, die das Team verlassen hat. Neue Kollegen lesen den Zwischenstand als Absicht. Ohne festgehaltene Begründung lässt sich eine Entscheidung nicht überprüfen, wenn sich die Randbedingungen ändern – also bleibt sie bestehen, lange nachdem ihr Grund entfallen ist.
Dazu kommen Schnittstellen, die als internes Detail begonnen haben und inzwischen von Dritten benutzt werden: ohne Versionierung, ohne dokumentiertes Fehlerverhalten, ohne Zusage zur Kompatibilität. Jede Änderung ist dann ein Risiko, das niemand einschätzen kann. Ähnlich wirkt die Bindung an einzelne Anbieter, wenn proprietäre Trigger, verwaltete Warteschlangen und anbieterspezifische Identitätsmodelle in die Geschäftslogik wandern und den Betriebsort faktisch festlegen.
Vorgehen
Am Anfang steht eine Bestandsaufnahme am realen System, nicht am Wunschbild. Wir lesen Repositories und Build-Definitionen, ziehen das Datenbankschema mit Fremdschlüsseln und Indizes, sehen uns die teuersten Abfragen über pg_stat_statements an und prüfen Deploymentweg und Laufzeitkonfiguration. Daraus entsteht ein Abhängigkeitsbild, das Kopplungen benennt: geteilte Tabellen, gemeinsam genutzte Bibliotheken, implizite Reihenfolgen bei Migrationen, Aufrufe ohne Zeitlimit.
Der Schnitt folgt Datenhoheit und Änderungsrhythmus, nicht dem Organigramm. Jede Komponente besitzt ihre Tabellen; Zugriff von außen läuft über einen Vertrag – ein HTTP-Interface mit OpenAPI-Beschreibung, ein Ereignisformat mit Schema oder eine bewusst offengelegte Sicht, etwa über PostgREST. Verträge werden versioniert, additiv erweitert und in der Pipeline gegen Beispieldaten geprüft. Fehlerfälle, Zeitlimits und Idempotenz gehören in die Spezifikation, nicht in den Kopf der Implementierung.
Jede tragende Entscheidung wird als Architecture Decision Record im Repository abgelegt, üblicherweise unter docs/adr/ und versioniert mit dem Code. Ein solcher Eintrag beschreibt Kontext, geprüfte Optionen, Entscheidung, Konsequenzen und Status – vorgeschlagen, akzeptiert oder ersetzt. Damit ist nachvollziehbar, welche Annahme eine Struktur trägt. Fällt die Annahme weg, ist der Eintrag der Ausgangspunkt für die Revision und nicht der Anlass, dieselbe Diskussion von vorn zu führen.
Modernisierung läuft schrittweise nach dem Strangler-Fig-Muster: Ein Reverse Proxy leitet einzelne Routen auf die neue Implementierung um, das alte System bleibt lauffähig, jeder Schritt ist für sich rückrollbar. Doppelschreiben und Abgleichläufe sichern die Datenwanderung ab. Parallel wird gemessen – OpenTelemetry-Traces über Dienstgrenzen, Fehlerquoten und Latenzverteilungen je Route. Ob ein Schnitt trägt, entscheidet die Telemetrie, nicht das Diagramm.
Leistungsumfang
01
02
03
04
05
06
07
Einsatzfälle
Ein gewachsenes System lässt sich nur als Ganzes deployen, jede Änderung erfordert eine Regression über alles. Wir bestimmen die ersten tragfähigen Schnitte und den Weg dorthin.
Viele Dienste, eine gemeinsame Datenbank, synchrone Aufrufketten. Wir führen zusammen, wo die Aufteilung nichts gebracht hat, und ziehen Verträge dort, wo Entkopplung wirklich nötig ist.
Ein Zielbild liegt vor, Budget und Zeitplan sind knapp. Wir prüfen Annahmen, Betriebsaufwand und Ausstiegskosten und benennen die Stellen, an denen der Plan bricht.
Eine zentrale Funktion hängt an einem Anbieterdienst mit steigenden Kosten. Wir bewerten offene Alternativen, planen Datenmigration und Parallelbetrieb und definieren Abbruchkriterien.
Ergebnis
Ablauf
Fragen
Das hängt davon ab, ob unabhängige Auslieferung und unabhängige Skalierung tatsächlich gebraucht werden. Ein gut geschnittener Monolith mit klaren Modulgrenzen und einer Datenbank ist für die meisten Teams der günstigere Ausgangspunkt, weil er verteilte Transaktionen, Netzfehler und zusätzlichen Betriebsaufwand vermeidet. Aufteilen lohnt sich dort, wo Teile eines Systems unterschiedliche Lastprofile, Freigabezyklen oder Verfügbarkeitsanforderungen haben. Diese Frage entscheiden wir pro Grenze, nicht pauschal für das ganze System.
Ja, das ist ein eigenständiger Auftrag. Wir lesen Code, Schema, Build und Betriebskonfiguration und liefern einen Befund mit priorisierten Risiken, benannten Kopplungen und Aufwandsschätzungen je Schritt. Sie können damit intern weiterarbeiten oder anschließend einzelne Schritte umsetzen lassen. Zum Befund gehört auch, was wir nicht prüfen konnten und welche Annahmen in der Bewertung stecken.
Eine belastbare Zahl gibt es erst nach der Bestandsaufnahme, weil Umfang und Risiko am Datenmodell und an der vorhandenen Testabdeckung hängen. Planbar ist dagegen der Zuschnitt der Schritte: Jeder einzelne Schritt soll innerhalb weniger Wochen produktiv gehen und rückrollbar sein. So entstehen früh nutzbare Ergebnisse, statt eines Projekts, dessen Nutzen erst am Ende eintritt.
Kontext und Auslöser der Entscheidung, die geprüften Optionen mit ihren Nachteilen, die getroffene Entscheidung, die Konsequenzen und der aktuelle Status. Die Einträge liegen als Markdown-Dateien unter docs/adr/ im Repository und werden mit dem Code versioniert. Ersetzt eine neue Entscheidung eine alte, wird die alte nicht gelöscht, sondern als ersetzt markiert und verlinkt.
Durch Trennung von Geschäftslogik und Plattformspezifika sowie durch Standards mit mehreren Implementierungen: SQL auf PostgreSQL, Container-Images nach OCI-Spezifikation, Telemetrie über OpenTelemetry, Infrastrukturbeschreibung im eigenen Repository. Anbieterspezifische Dienste werden hinter einer eigenen Schnittstelle isoliert, sodass sich der Aufwand eines Wechsels vorab abschätzen lässt. Vollständige Unabhängigkeit ist selten das Ziel – bekannte Ausstiegskosten dagegen immer.
Verwandte Leistungen
02 / 06
ENGINEERING
05 / 06
DELIVERY
06 / 06
CONSULTING
Fachartikel dazu
Warum der Big-Bang-Rewrite scheitert und wie Altsysteme im laufenden Betrieb umgebaut werden: Sicherheitsnetz, Nähte, Strangler Fig, Datenbankmigration.
Lock-in ist ein Preis, kein Denkfehler. Wie Sie Daten-, API-, Betriebs- und Vertragsbindung erkennen, Exit-Kosten beziffern und Portabilität wirklich testen.
Eine Open-Source-Strategie regelt verbindlich, welche Fremdkomponenten hereinkommen, was veröffentlicht wird und wer entscheidet. Aufbau, Rollen, Einführung.
Kontakt
Beschreiben Sie kurz Ihr System und die offene Frage. Wir antworten mit einer fachlichen Einschätzung – ohne Vertriebsschleife.