Competing-Consumer-Entwurfsmuster: Unterschied zwischen den Versionen
PhilKa (Diskussion | Beiträge) Die Seite wurde neu angelegt: „= Competing-Consumer-Entwurfsmuster = Das '''Competing-Consumer-Entwurfsmuster''' ist ein Architektur- und Integrationsmuster, das zur Lastverteilung und parallelen Verarbeitung von Nachrichten oder Aufgaben in verteilten Systemen eingesetzt wird. Mehrere Consumer greifen dabei auf eine gemeinsame Nachrichtenquelle (z. B. eine Queue) zu. Jede Nachricht wird genau von einem Consumer verarbeitet, wodurch sich die Last automatisch verteilt und das System…“ |
PhilKa (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
||
| Zeile 6: | Zeile 6: | ||
== Ziel == | == Ziel == | ||
Das Muster wird verwendet, um: | Das Muster wird verwendet, um: | ||
* | * ''Parallelisierung'' der Verarbeitung zu erreichen | ||
* | * ''Last gleichmäßig zu verteilen'' | ||
* | * ''Durchsatz zu erhöhen'' | ||
* | * ''Skalierbarkeit durch Hinzufügen weiterer Consumer'' zu ermöglichen | ||
* | * ''Fehlertoleranz'' zu verbessern (bei Ausfall eines Consumers arbeiten andere weiter) | ||
== Grundprinzip == | == Grundprinzip == | ||
Eine Nachrichtenquelle (häufig eine Queue in einem Message-Broker) speichert Aufgaben oder Nachrichten. | Eine Nachrichtenquelle (häufig eine Queue in einem Message-Broker) speichert Aufgaben oder Nachrichten. | ||
Mehrere Consumer abonnieren dieselbe Queue und „konkurrieren“ um eingehende Nachrichten. | Mehrere Consumer abonnieren dieselbe Queue und „konkurrieren“ um eingehende Nachrichten. | ||
Der Broker stellt sicher, dass jede Nachricht | Der Broker stellt sicher, dass jede Nachricht ''nur von einem Consumer'' verarbeitet wird. | ||
=== Grafische Darstellung === | === Grafische Darstellung === | ||
| Zeile 40: | Zeile 40: | ||
== Ablauf == | == Ablauf == | ||
1. Der | 1. Der ''Producer'' erzeugt Nachrichten und legt sie in die ''Queue''. | ||
2. Mehrere | 2. Mehrere ''Consumer'' sind gleichzeitig auf die Queue registriert. | ||
3. Sobald eine Nachricht verfügbar ist, erhält | 3. Sobald eine Nachricht verfügbar ist, erhält ''ein einzelner Consumer'' diese zur Verarbeitung. | ||
4. Nach erfolgreicher Verarbeitung bestätigt der Consumer den Erhalt (Ack). | 4. Nach erfolgreicher Verarbeitung bestätigt der Consumer den Erhalt (Ack). | ||
5. Die Queue löscht die Nachricht oder stellt sie anderen Consumer bereit, falls ein Fehler auftritt. | 5. Die Queue löscht die Nachricht oder stellt sie anderen Consumer bereit, falls ein Fehler auftritt. | ||
== Eigenschaften == | == Eigenschaften == | ||
* Die Verarbeitung erfolgt | * Die Verarbeitung erfolgt ''asynchron''. | ||
* Die Consumer arbeiten | * Die Consumer arbeiten ''unabhängig'' voneinander. | ||
* Die Lastverteilung erfolgt | * Die Lastverteilung erfolgt ''automatisch'' durch den Broker. | ||
* Verarbeitung ist | * Verarbeitung ist ''skalierbar'', indem weitere Consumer hinzugefügt werden. | ||
== Einsatzgebiete == | == Einsatzgebiete == | ||
Das Muster wird häufig verwendet in: | Das Muster wird häufig verwendet in: | ||
* | * ''Microservices-Architekturen'' | ||
* | * ''Event-driven Systems'' | ||
* | * ''Hintergrundverarbeitung (Worker Jobs)'' | ||
* | * ''Verteilten Task-Pipelines'' | ||
* | * ''Message-Brokern'' wie RabbitMQ, Kafka, ActiveMQ | ||
== Beispiel in RabbitMQ (Pseudocode) == | == Beispiel in RabbitMQ (Pseudocode) == | ||
| Zeile 85: | Zeile 85: | ||
== Vorteile == | == Vorteile == | ||
* | * ''Erhöhte Performance'': Mehr Consumer → schnellerer Durchsatz | ||
* | * ''Robustheit'': Ausfall einzelner Consumer beeinträchtigt den Prozess nicht | ||
* | * ''Dynamische Skalierung'': Consumer können zur Laufzeit hinzugefügt oder entfernt werden | ||
* | * ''Ressourcenoptimierung'': Jeder Consumer verarbeitet genau eine Nachricht zur Zeit | ||
== Nachteile == | == Nachteile == | ||
* | * ''Keine garantierte Reihenfolge'' der Verarbeitung | ||
* | * ''Zustandsverwaltung schwierig'', wenn Aufgaben voneinander abhängen | ||
* | * ''Monitoring notwendig'', um Engpässe zu erkennen (z. B. zu viele oder zu wenige Consumer) | ||
* | * ''Systemkomplexität'' steigt, wenn Fehlerbehandlung und Retry-Mechanismen berücksichtigt werden | ||
== Best Practices == | == Best Practices == | ||
* Consumer möglichst | * Consumer möglichst ''zustandslos'' gestalten | ||
* | * ''Idempotente Verarbeitung'' sicherstellen (mehrfache Verarbeitung darf keine Fehler verursachen) | ||
* Nachrichtengröße gering halten → bessere Performance | * Nachrichtengröße gering halten → bessere Performance | ||
* Monitoring von: | * Monitoring von: | ||
| Zeile 106: | Zeile 106: | ||
== Zusammenfassung == | == Zusammenfassung == | ||
Das Competing-Consumer-Entwurfsmuster ermöglicht eine | Das Competing-Consumer-Entwurfsmuster ermöglicht eine ''effiziente, skalierbare und fehlertolerante Verarbeitung'' von Aufgaben in verteilten Systemen. | ||
Mehrere Consumer konkurrieren um Nachrichten in einer gemeinsamen Queue, wobei jede Nachricht von genau einem Consumer verarbeitet wird. | Mehrere Consumer konkurrieren um Nachrichten in einer gemeinsamen Queue, wobei jede Nachricht von genau einem Consumer verarbeitet wird. | ||
Durch Hinzufügen weiterer Consumer kann die Verarbeitungslast problemlos erhöht werden. | Durch Hinzufügen weiterer Consumer kann die Verarbeitungslast problemlos erhöht werden. | ||
Aktuelle Version vom 8. November 2025, 14:01 Uhr
Competing-Consumer-Entwurfsmuster
Das Competing-Consumer-Entwurfsmuster ist ein Architektur- und Integrationsmuster, das zur Lastverteilung und parallelen Verarbeitung von Nachrichten oder Aufgaben in verteilten Systemen eingesetzt wird. Mehrere Consumer greifen dabei auf eine gemeinsame Nachrichtenquelle (z. B. eine Queue) zu. Jede Nachricht wird genau von einem Consumer verarbeitet, wodurch sich die Last automatisch verteilt und das System horizontal skaliert.
Ziel
Das Muster wird verwendet, um:
- Parallelisierung der Verarbeitung zu erreichen
- Last gleichmäßig zu verteilen
- Durchsatz zu erhöhen
- Skalierbarkeit durch Hinzufügen weiterer Consumer zu ermöglichen
- Fehlertoleranz zu verbessern (bei Ausfall eines Consumers arbeiten andere weiter)
Grundprinzip
Eine Nachrichtenquelle (häufig eine Queue in einem Message-Broker) speichert Aufgaben oder Nachrichten. Mehrere Consumer abonnieren dieselbe Queue und „konkurrieren“ um eingehende Nachrichten. Der Broker stellt sicher, dass jede Nachricht nur von einem Consumer verarbeitet wird.
Grafische Darstellung
+----------------+
| Producer |
| (stellt Tasks) |
+--------+-------+
|
v
+---------------+
| Queue |
| (Warteschlange|
+-------+-------+
|
+----------------+----------------+
| | |
v v v
+---------------+ +---------------+ +---------------+
| Consumer 1 | | Consumer 2 | | Consumer 3 |
| (verarbeitet) | | (verarbeitet) | | (verarbeitet) |
+---------------+ +---------------+ +---------------+
Ablauf
1. Der Producer erzeugt Nachrichten und legt sie in die Queue. 2. Mehrere Consumer sind gleichzeitig auf die Queue registriert. 3. Sobald eine Nachricht verfügbar ist, erhält ein einzelner Consumer diese zur Verarbeitung. 4. Nach erfolgreicher Verarbeitung bestätigt der Consumer den Erhalt (Ack). 5. Die Queue löscht die Nachricht oder stellt sie anderen Consumer bereit, falls ein Fehler auftritt.
Eigenschaften
- Die Verarbeitung erfolgt asynchron.
- Die Consumer arbeiten unabhängig voneinander.
- Die Lastverteilung erfolgt automatisch durch den Broker.
- Verarbeitung ist skalierbar, indem weitere Consumer hinzugefügt werden.
Einsatzgebiete
Das Muster wird häufig verwendet in:
- Microservices-Architekturen
- Event-driven Systems
- Hintergrundverarbeitung (Worker Jobs)
- Verteilten Task-Pipelines
- Message-Brokern wie RabbitMQ, Kafka, ActiveMQ
Beispiel in RabbitMQ (Pseudocode)
Producer
channel.basic_publish(
exchange='',
routing_key='task_queue',
body='Aufgabe 1'
)
Consumer (mehrfach gestartet)
def callback(ch, method, properties, body):
print(f"Verarbeite: {body}")
ch.basic_ack(delivery_tag=method.delivery_tag)
channel.basic_qos(prefetch_count=1)
channel.basic_consume(queue='task_queue', on_message_callback=callback)
channel.start_consuming()
Hiermit arbeiten mehrere Instanzen dieses Consumers parallel.
Vorteile
- Erhöhte Performance: Mehr Consumer → schnellerer Durchsatz
- Robustheit: Ausfall einzelner Consumer beeinträchtigt den Prozess nicht
- Dynamische Skalierung: Consumer können zur Laufzeit hinzugefügt oder entfernt werden
- Ressourcenoptimierung: Jeder Consumer verarbeitet genau eine Nachricht zur Zeit
Nachteile
- Keine garantierte Reihenfolge der Verarbeitung
- Zustandsverwaltung schwierig, wenn Aufgaben voneinander abhängen
- Monitoring notwendig, um Engpässe zu erkennen (z. B. zu viele oder zu wenige Consumer)
- Systemkomplexität steigt, wenn Fehlerbehandlung und Retry-Mechanismen berücksichtigt werden
Best Practices
- Consumer möglichst zustandslos gestalten
- Idempotente Verarbeitung sicherstellen (mehrfache Verarbeitung darf keine Fehler verursachen)
- Nachrichtengröße gering halten → bessere Performance
- Monitoring von:
* Queue-Länge * Durchsatz * Fehlerrate
Zusammenfassung
Das Competing-Consumer-Entwurfsmuster ermöglicht eine effiziente, skalierbare und fehlertolerante Verarbeitung von Aufgaben in verteilten Systemen. Mehrere Consumer konkurrieren um Nachrichten in einer gemeinsamen Queue, wobei jede Nachricht von genau einem Consumer verarbeitet wird. Durch Hinzufügen weiterer Consumer kann die Verarbeitungslast problemlos erhöht werden.