Event-Driven Architecture (EDA)
Event-Driven Architecture (EDA)
Die Event-Driven Architecture (kurz: EDA, deutsch: Ereignisgesteuerte Architektur) ist ein Architekturstil in der Softwareentwicklung, bei dem der Informationsfluss durch das Eintreten und die Verarbeitung von Ereignissen gesteuert wird.
Anstatt dass Komponenten direkt miteinander interagieren, kommunizieren sie über Ereignisse (Events), die von einem oder mehreren Event-Handlern oder Subscribers verarbeitet werden.
Grundprinzip
Im Zentrum der ereignisgesteuerten Architektur steht die Idee, dass Systeme auf das Eintreten von Ereignissen reagieren, anstatt zyklisch Zustände zu prüfen oder direkt Funktionen aufzurufen.
Ein „Event“ ist dabei eine Nachricht, die signalisiert, dass etwas passiert ist (z. B. „Bestellung eingegangen“, „Sensorwert geändert“, „Benutzer klickte auf Button“).
+--------------------+ +--------------------+ +--------------------+ | Event Source | -----> | Event Broker | -----> | Event Handler | | (Producer/Sender) | | (Message Queue) | | (Consumer/Listener)| +--------------------+ +--------------------+ +--------------------+
Hauptkomponenten
| Komponente | Beschreibung |
|---|---|
| Event Producer | Erzeugt Ereignisse (z. B. Benutzeraktionen, Sensoren, Microservices) |
| Event Channel / Broker | Transportiert Ereignisse asynchron (z. B. Message Queue, Event Bus) |
| Event Consumer | Reagiert auf bestimmte Ereignisse und führt entsprechende Aktionen aus |
| Event Store | Optionale persistente Speicherung vergangener Ereignisse (z. B. für Event Sourcing) |
Ablauf
1. Ein Producer erzeugt ein Event („Bestellung wurde aufgegeben“). 2. Das Event wird an einen Broker (z. B. RabbitMQ, Kafka) gesendet. 3. Der Broker leitet das Event an alle interessierten Consumer weiter. 4. Jeder Consumer reagiert unabhängig auf das Ereignis.
Beispiel in Pseudo-C++
Ein vereinfachtes Beispiel für ein ereignisgesteuertes System:
#include <iostream>
#include <functional>
#include <map>
#include <vector>
#include <string>
class EventBus {
std::map<std::string, std::vector<std::function<void(std::string)>>> subscribers;
public:
void subscribe(const std::string& event, std::function<void(std::string)> handler) {
subscribers[event].push_back(handler);
}
void publish(const std::string& event, const std::string& data) {
for (auto& handler : subscribers[event]) {
handler(data);
}
}
};
int main() {
EventBus bus;
// Subscriber registrieren
bus.subscribe("order_created", [](std::string msg){
std::cout << "E-Mail-Service: Sende Bestellbestätigung für " << msg << std::endl;
});
bus.subscribe("order_created", [](std::string msg){
std::cout << "Lager-Service: Reserviere Artikel für " << msg << std::endl;
});
// Event auslösen
bus.publish("order_created", "Bestellung #1234");
}
Ergebnis:
E-Mail-Service: Sende Bestellbestätigung für Bestellung #1234 Lager-Service: Reserviere Artikel für Bestellung #1234
Architekturmuster
Ereignisgesteuerte Architekturen lassen sich in verschiedene Unterarten gliedern:
1. Einfaches Event-Notification-Modell
Ein Sender informiert Empfänger direkt über ein Ereignis (z. B. Observer-Entwurfsmuster).
2. Event-Carried State Transfer
Das Event enthält die notwendigen Daten, damit Empfänger unabhängig agieren können.
3. Event Sourcing
Zustände werden nicht direkt gespeichert, sondern als Abfolge von Ereignissen (z. B. „Konto eröffnet“, „Geld eingezahlt“). Der aktuelle Zustand wird aus allen Events rekonstruiert.
4. Complex Event Processing (CEP)
Systeme analysieren Muster in einer Vielzahl von Ereignissen in Echtzeit (z. B. Anomalieerkennung, IoT-Systeme).
Vorteile
- Hohe **Entkopplung** zwischen Komponenten
- Bessere **Skalierbarkeit** und **Asynchronität**
- Gute **Erweiterbarkeit** – neue Event-Handler können leicht hinzugefügt werden
- Ideal für **Microservices** und **verteilte Systeme**
Nachteile
- Komplexeres Debugging und Monitoring
- Schwierige Transaktions- und Konsistenzsicherung
- Höherer Aufwand für Event-Schema-Management
- Event-Reihenfolge und -Duplikate müssen berücksichtigt werden
Typische Implementierungen
- Message Broker / Event Bus Systeme:
* **Apache Kafka** * **RabbitMQ** * **ActiveMQ** * **AWS SNS/SQS** * **Azure Event Hub**
- Asynchrone Frameworks:
* **Node.js (Event Loop)** * **Boost.Asio (C++)** * **.NET Event System** * **Akka (Scala/Java)**
Vergleich zu anderen Architekturstilen
| Architekturstil | Merkmale | Kommunikation |
|---|---|---|
| Service-Oriented Architecture (SOA) | Dienste kommunizieren direkt über Schnittstellen | synchron (Request/Response) |
| Event-Driven Architecture | Dienste reagieren auf Ereignisse | asynchron (Publish/Subscribe) |
| Reactor-Entwurfsmuster | Low-Level-Ereignissteuerung (z. B. Socket-I/O) | synchron, nicht-blockierend |
| Observer-Entwurfsmuster | Lokales Ereignissystem in Objektorientierung | direkt in einer Anwendung |
Beispielhafte Anwendungsbereiche
- Microservices-Kommunikation
- IoT- und Sensordatenverarbeitung
- Finanztransaktionen und Echtzeit-Analysen
- Logging- und Monitoring-Systeme
- Chat- oder Benachrichtigungssysteme
Erweiterte Konzepte
- Event Choreography: Dienste reagieren eigenständig auf Events (dezentrale Logik)
- Event Orchestration: Zentrale Steuerung der Reaktionen auf Events (z. B. via Workflow Engine)
- Event Replay: Nachträgliches Wiederholen von Events für Auditing oder Recovery
- Idempotenz: Sicherstellung, dass doppelt verarbeitete Events keine fehlerhaften Zustände erzeugen
Beispielhafte Kombination mit Entwurfsmustern
- Observer-Entwurfsmuster – lokale Implementierung innerhalb eines Prozesses
- Reactor-Entwurfsmuster – effiziente Ereignisverarbeitung auf Systemebene
- Proactor-Entwurfsmuster – asynchrone Verarbeitung von I/O-Ereignissen
- Mediator-Entwurfsmuster – Koordination von Events über zentrale Vermittler
Siehe auch
- Observer-Entwurfsmuster
- Reactor-Entwurfsmuster
- Proactor-Entwurfsmuster
- Publisher-Subscriber-Muster
- Service-Oriented Architecture (SOA)
- Microservices-Architektur
Quellen
- O. Zimmermann et al.: *Architectural Decisions for Event-Driven Architectures*, IEEE Software (2020)
- Martin Fowler: What do you mean by “Event-Driven”?
- Wikipedia: Event-Driven Architecture
- *Enterprise Integration Patterns* – Gregor Hohpe, Bobby Woolf (2003)