Publisher-Subscriber-Entwurfsmuster
Publisher-Subscriber-Entwurfsmuster
Das Publisher-Subscriber-Entwurfsmuster (kurz: Pub/Sub) ist ein **Verhaltens- und Integrationsmuster**, das die **asynchrone, lose gekoppelte Kommunikation** zwischen Softwarekomponenten ermöglicht. Statt dass Sender (Publisher) Nachrichten direkt an Empfänger (Subscriber) senden, werden diese über eine **vermittelnde Instanz** (z. B. Message Broker oder Event-Bus) verteilt.
Ziel
Das Muster soll:
- **Abhängigkeiten zwischen Sender und Empfänger vermeiden**
- **Asynchrone Kommunikationsabläufe ermöglichen**
- **Skalierbarkeit verbessern**
- **Flexibilität und Erweiterbarkeit des Systems erhöhen**
- **Ereignisgesteuerte Architekturen unterstützen**
Grundprinzip
Komponenten, die Nachrichten senden möchten, veröffentlichen diese bei einem **Publisher** oder über einen **Message Broker**. Komponenten, die Nachrichten empfangen möchten, registrieren sich (abonnieren) bei einem **Subscriber**-Interface oder beim Broker. Der Publisher kennt die Subscriber **nicht** direkt.
Grafische Darstellung
Publisher Subscriber
(Sendet Events) (Empfängt Events)
| ^
| |
v |
+--------- Message Broker --------+
Komponenten
| Komponente | Rolle |
|---|---|
| **Publisher** | Erzeugt und veröffentlicht Nachrichten/Ereignisse. |
| **Subscriber** | Registriert sich für bestimmte Nachrichten und verarbeitet sie. |
| **Broker / Event Bus** | Vermittelt Nachrichten zwischen Publishern und Subscribern. |
Ablauf
1. Der **Subscriber** meldet sich beim Broker für bestimmte Themen oder Ereignisse an. 2. Der **Publisher** sendet eine Nachricht an den Broker. 3. Der Broker verteilt die Nachricht automatisch an alle relevanten Subscriber. 4. Die Subscriber verarbeiten die Nachricht unabhängig voneinander.
Themenbasierte vs. ereignisbasierte Varianten
Themenbasiert (Topic-based)
Subscriber abonnieren Nachrichten zu bestimmten **Themen (Topics)**. Beispiel:
topic = "sensor/temperatur"
Alle Subscriber dieses Topics erhalten die Nachrichten.
Ereignisbasiert (Event-based)
Nachrichten definieren **spezifische Ereignisse**, z. B.:
Event: "Benutzer wurde erstellt"
Nur Subscriber dieses Ereignisses werden informiert.
Beispiel in Python (vereinfachter Event-Bus)
class EventBus:
def __init__(self):
self.subscribers = {}
def subscribe(self, event, callback):
self.subscribers.setdefault(event, []).append(callback)
def publish(self, event, data):
for callback in self.subscribers.get(event, []):
callback(data)
bus = EventBus()
def handler(msg):
print("Empfangen:", msg)
bus.subscribe("test_event", handler)
bus.publish("test_event", "Hallo Pub/Sub")
Beispiele in realen Systemen
| System | Rolle | |-------|-------| | **RabbitMQ** | Topic/Fanout Exchanges für Pub/Sub | | **Apache Kafka** | Verteilt Nachrichtenströme an Consumer-Gruppen | | **Redis Pub/Sub** | Leichtgewichtiges Pub/Sub-Modell in Infrastrukturanwendungen | | **WebSockets / Socket.IO** | Ereignisbasierte Kommunikation in Echtzeit-Anwendungen | | **Cloud Pub/Sub (Google/AWS/Azure)** | Globale Messaging-Systeme für verteilte Microservices |
Vorteile
- **Lose Kopplung** zwischen Komponenten
- **Hohe Skalierbarkeit** durch parallele Verarbeitung
- **Unterstützt verteilte und eventgesteuerte Architekturen**
- **Wiederverwendbarkeit und Erweiterbarkeit** der Systemkomponenten
Nachteile
- **Nachrichtenfluss nicht direkt nachvollziehbar** (Debugging komplexer)
- **Keine garantierte Reihenfolge**, wenn nicht explizit unterstützt
- **Fehlerhandling und Retry-Strategien** müssen bewusst implementiert werden
- Potenzielle **Zustandsinkonsistenzen**, wenn Ereignisse zeitlich variieren
Best Practices
- Nachrichten **idempotent** verarbeiten (Doppelausführung darf keine Fehler verursachen)
- **Monitoring von Queues und Topics**
- Verwendung eines **zentralen Event-Schemas** bei verteilten Teams
- Klare **Namenskonventionen** für Topics/Ereignisse
Vergleich zu anderen Mustern
| Muster | Vergleichspunkt | Unterschied |
|---|---|---|
| Pub/Sub | Kommunikation | Asynchron und entkoppelt |
| Observer | Kommunikation | Direkte Objektbeziehung ohne Broker |
| Competing Consumer | Verarbeitung | Mehrere Consumer teilen sich eine Queue (Lastverteilung), aber ohne Broadcast an mehrere Empfänger |
Zusammenfassung
Das Publisher-Subscriber-Entwurfsmuster ermöglicht **asynchrone, lose gekoppelte Kommunikation** zwischen Softwarekomponenten. Publisher senden Ereignisse ohne Wissen über Empfänger, während Subscriber flexibel Ereignisse abonnieren. Es bildet das Fundament vieler **eventgesteuerter, verteilter und skalierbarer Softwaresysteme**.
Siehe auch
- Competing-Consumer-Entwurfsmuster
- Mediator-Entwurfsmuster
- Event-Driven Architecture
- RabbitMQ
- Apache Kafka