Eine Message Queue entkoppelt die Systeme, die Arbeit erzeugen, von den Systemen, die sie erledigen. Producer übergeben Nachrichten an einen Broker und machen weiter; Consumer verarbeiten sie in ihrem eigenen Tempo. Das verschafft Ihnen Pufferung bei Traffic-Spitzen, Retries beim Ausfall eines Consumers und die Möglichkeit, Producer und Consumer unabhängig voneinander zu skalieren — weshalb asynchrones Messaging das Fundament der meisten ernsthaften Microservices-Architekturen bildet.

Das AMQP-Modell: Exchanges, Bindings, Routing Keys

RabbitMQ ist ein Message Broker, der um AMQP 0-9-1 herum gebaut ist; native AMQP-1.0-Unterstützung kam mit der RabbitMQ-4.x-Serie hinzu. Der Teil, den die meisten Einführungen überspringen: Producer in RabbitMQ publizieren nicht in Queues — sie publizieren an Exchanges, und Bindings entscheiden anhand des Routing Keys, welche Queues die jeweilige Nachricht erhalten. Die Exchange-Typen definieren das Routing-Verhalten: direct (exakte Übereinstimmung des Routing Keys), topic (Mustervergleich, z. B. orders.*.created), fanout (Broadcast an jede gebundene Queue) und headers. Diese Routing-Schicht ist die Kernstärke von RabbitMQ: Ein einziges publiziertes Event kann sich auf eine Work Queue, eine Audit Queue und eine Notification Queue verteilen, ohne dass der Producer von einer davon weiß.

Auf der Queue-Seite bietet RabbitMQ 4.x Classic Queues, Quorum Queues (Raft-repliziert, die Standardwahl für alles, was zählt — Classic Mirrored Queues wurden in 4.0 entfernt) sowie Streams, einen append-only, wieder abspielbaren Log-Typ für Kafka-artige Anwendungsfälle.

Persistenz ist Opt-in, nicht Standard

Queue-Systeme verhindern Nachrichtenverlust nicht automatisch. In RabbitMQ erfordert das Überstehen eines Broker-Neustarts drei bewusste Entscheidungen: die Queue als durable deklarieren, Nachrichten als persistent publizieren und Publisher Confirms aktivieren, damit der Producer weiß, dass der Broker die Nachricht tatsächlich geschrieben hat. Auf der Consumer-Seite verwenden Sie manuelle Acknowledgements, die nach erfolgreicher Verarbeitung gesendet werden, mit einem vernünftigen Prefetch-Limit — Auto-Ack bedeutet, dass ein Consumer-Absturz die gerade unterwegs befindlichen Nachrichten stillschweigend verwirft. Lassen Sie einen dieser Punkte aus, und Sie werden irgendwann den klassischen Bug-Report schreiben: „Die Queue hat meine Nachricht verloren.“

Zustellgarantien und Idempotenz

Die Garantien, die Sie realistisch bekommen können, sind at-most-once oder at-least-once. At-least-once — die nützliche Variante — bedeutet Duplikate: Stürzt ein Consumer nach der Verarbeitung, aber vor dem Acknowledgement ab, wird die Nachricht erneut zugestellt. Ende-zu-Ende-Exactly-once über unabhängige Systeme hinweg ist in der Praxis nicht erreichbar; Sie nähern sich dem Effekt an, indem Sie Ihre Consumer idempotent machen — Deduplizierungs-Keys, Upserts, bedingte Schreibvorgänge —, sodass die doppelte Verarbeitung derselben Nachricht nichts verändert.

Beim Thema Reihenfolge ist dieselbe Ehrlichkeit angebracht. Nachrichten in einer Queue werden geordnet gespeichert, aber strikte Reihenfolge bleibt nur mit einem einzelnen Consumer erhalten. Sobald Sie auf mehrere konkurrierende Consumer skalieren — das normale Muster —, werden Nachrichten außer der Reihe fertig. Wenn die Reihenfolge pro Entität zählt, brauchen Sie Partition-Key-Semantik (Kafka oder SQS-FIFO-Message-Groups), nicht eine größere RabbitMQ-Queue.

Dead-Letter-Queues

Eine fehlerhafte „Poison Message“, die ihren Consumer zum Absturz bringt, würde sonst endlos erneut zugestellt und alles hinter sich blockieren. RabbitMQ löst das mit einem Dead-Letter-Exchange (DLX): Abgelehnte oder abgelaufene Nachrichten werden zur Inspektion in eine Halte-Queue umgeleitet. SQS macht dasselbe mit einer Redrive Policy und maxReceiveCount. Kombinieren Sie Dead-Lettering mit begrenzten Retries und Backoff, und alarmieren Sie auf die DLQ-Tiefe — eine wachsende Dead-Letter-Queue ist ein Incident, den jeder der von uns empfohlenen Monitoring-Stacks kostengünstig sichtbar machen kann.

RabbitMQ vs. Kafka vs. SQS

RabbitMQ ist ein smarter Broker: reichhaltiges Routing, Acknowledgements pro Nachricht, Prioritäten, latenzarme Work Queues und RPC-Muster. Eine konsumierte Nachricht ist weg. Wählen Sie es für Aufgabenverteilung und komplexes Routing zwischen Services, die Sie selbst betreiben.

Kafka ist keine Queue, sondern ein verteiltes, repliziertes Log. Nachrichten werden für einen konfigurierten Zeitraum aufbewahrt und können erneut abgespielt werden; Consumer Groups verwalten ihre eigenen Offsets; die Reihenfolge ist pro Partition garantiert, sodass Ordnung pro Key skaliert. Wählen Sie es für Event Streaming, Event Sourcing und Pipelines mit hohem Durchsatz und mehreren unabhängigen Consumern — und kalkulieren Sie sein operatives Gewicht oder einen Managed Service ein.

Amazon SQS ist eine vollständig verwaltete Queue: At-least-once-Standard-Queues mit praktisch unbegrenztem Durchsatz oder FIFO-Queues, wenn Sie Reihenfolge und Deduplizierung bei geringerem Durchsatz brauchen. Eine Routing-Schicht gibt es nicht — kombinieren Sie es für Fanout mit SNS oder EventBridge. Wenn Sie auf AWS laufen und Ihre Anforderungen queue-förmig sind, ist SQS der pragmatische Standard, weil kein Broker zu betreiben ist.

Die Kurzfassung: Nutzen Sie eine Queue (RabbitMQ, SQS) für Kommandos und Hintergrund-Jobs, die einmal verarbeitet werden; nutzen Sie ein Log (Kafka) für Events, die viele Consumer lesen oder erneut abspielen. Diese Schicht richtig aufzubauen — Persistenz-Einstellungen, idempotente Consumer, Dead-Lettering, Alerting — ist genau die Art von Fundament, die unser DevOps-Engineering-Team in Delivery-Pipelines und Produktionsplattformen einbaut.

Sie betreiben so etwas in Produktion? Unser AWS Managed Services-Team betreibt solche Umgebungen rund um die Uhr — Monitoring, Incident Response, Patching und Kostenkontrolle durch namentlich benannte Senior Engineers, ab €3.000/Monat.