Streamlined Keycloak configurations with defaults for development and production in `.env`. Added health checks and improved environment variable documentation with comments to differentiate local and server deployments. Ensured compatibility with pre-built registry images.
4.8 KiB
| type | status | owner |
|---|---|---|
| ADR | ACTIVE | Lead Architect |
ADR-0003: Microservices-Architektur
Status
Akzeptiert
Kontext
Nach der Entscheidung, eine modulare Architektur (ADR-0001) und Domain-Driven Design (ADR-0002) zu übernehmen, mussten wir die Deployment-Strategie für unsere Module festlegen. Zu den wichtigsten Überlegungen gehörten:
- Unabhängige Skalierbarkeit verschiedener Teile des Systems
- Deployment-Unabhängigkeit, um Teams zu ermöglichen, Änderungen ohne Koordination mit anderen Teams zu veröffentlichen
- Technologieunabhängigkeit, um verschiedenen Diensten die Verwendung unterschiedlicher Technologien nach Bedarf zu ermöglichen
- Resilienz, um sicherzustellen, dass Ausfälle in einem Teil des Systems nicht das gesamte System beeinträchtigen
- Klare Zuständigkeitsgrenzen, die mit den Team-Verantwortlichkeiten übereinstimmen
Entscheidung
Wir haben uns entschieden, eine Microservices-Architektur zu implementieren, bei der jedes Domänenmodul als separater Dienst bereitgestellt wird:
- masterdata-service: Verwaltet Stammdaten wie Standorte, Disziplinen usw.
- members-service: Verwaltet Mitgliederregistrierung und -profile
- horses-service: Verwaltet Pferderegistrierung und -informationen
- events-service: Verwaltet Veranstaltungserstellung, -planung und -anmeldungen
Jeder Dienst:
- Hat sein eigenes Datenbankschema
- Ist unabhängig bereitstellbar
- Kommuniziert mit anderen Diensten über klar definierte APIs und nachrichtenbasierte Kommunikation
- Ist für seine eigene Domänenlogik gemäß DDD-Prinzipien verantwortlich
Wir haben auch unterstützende Infrastrukturdienste implementiert:
- gateway: API-Gateway für Routing und Authentifizierung
- auth: Authentifizierung- und Autorisierungsdienst (Keycloak)
- cache: Caching-Dienst (Redis)
- messaging: Message Broker für die Kommunikation zwischen Diensten (Kafka)
- monitoring: Überwachung- und Beobachtbarkeitsdienste
Konsequenzen
Positive
- Unabhängige Skalierbarkeit: Jeder Dienst kann basierend auf seinen spezifischen Lastanforderungen skaliert werden
- Deployment-Unabhängigkeit: Teams können Änderungen an ihren Diensten bereitstellen, ohne sich mit anderen Teams abstimmen zu müssen
- Technologieflexibilität: Verschiedene Dienste können je nach Bedarf unterschiedliche Technologien verwenden
- Resilienz: Ausfälle in einem Dienst beeinträchtigen nicht unbedingt andere
- Klare Zuständigkeit: Jeder Dienst hat klare Zuständigkeitsgrenzen, die mit den Team-Verantwortlichkeiten übereinstimmen
- Kleinere Codebasen: Jeder Dienst hat eine kleinere, fokussierte Codebasis
Negative
- Komplexität verteilter Systeme: Microservices bringen die Herausforderungen verteilter Systeme mit sich
- Betrieblicher Mehraufwand: Mehr Dienste müssen bereitgestellt, überwacht und gewartet werden
- Herausforderungen bei der Datenkonsistenz: Die Aufrechterhaltung der Datenkonsistenz über Dienste hinweg erfordert sorgfältiges Design
- Netzwerklatenz: Die Kommunikation zwischen Diensten fügt Latenz hinzu
- Testkomplexität: End-to-End-Tests werden komplexer
Neutral
- Teamorganisation: Teams müssen um Dienste statt um Features herum organisiert werden
- Dokumentationsbedarf: Dienstschnittstellen und -interaktionen müssen gut dokumentiert sein
Betrachtete Alternativen
Modularer Monolith
Wir haben die Implementierung eines modularen Monolithen in Betracht gezogen, bei dem alle Module als eine einzige Anwendung bereitgestellt werden, jedoch mit klaren Modulgrenzen. Dies wäre einfacher bereitzustellen gewesen und hätte die Herausforderungen verteilter Systeme vermieden, hätte aber nicht die Vorteile der unabhängigen Skalierbarkeit und Bereitstellung geboten.
Service-basierte Architektur
Wir haben eine Dienst-basierte Architektur mit weniger bzw. größeren Diensten in Betracht gezogen, die mehrere Domänenbereiche umfassen würden. Dies hätte den betrieblichen Overhead reduziert, aber es schwieriger gemacht, klare Domänengrenzen und unabhängige Skalierbarkeit aufrechtzuerhalten.