1. RabbitMQ: Zeitpunkt und Kontext
Wenn wir RabbitMQ ganz am Anfang des Kurses hinzugefügt hätten, sähe das zwar spektakulär aus, wäre methodisch aber so, als würde man Autofahren gleich mit einem Rennwagen lernen wollen: an sich cool, aber man ist sich noch nicht sicher, wo das Bremspedal ist, und landet sehr schnell im Gebüsch. RabbitMQ ist nicht „schwerer als Docker“, es fügt lediglich einen weiteren Abhängigkeitstyp hinzu, den man in einer Compose-Umgebung hochziehen, konfigurieren und diagnostizieren können muss.
Genau jetzt haben wir eine stabile Basis: der Stack app + postgres + redis funktioniert, Profile haben sich nicht in ein Konfigurationslabyrinth verwandelt, und Logs lesen wir nicht mehr wie Belletristik, sondern als technische Beweise. RabbitMQ fügt man sinnvollerweise nach diesem Fundament hinzu, denn sonst sieht jeder Fehler gleich aus: „alles ist kaputt“, und man kann nicht unterscheiden, was genau kaputt ist – die Datenbank, der Cache, die Anwendung oder der Glaube an localhost.
Es gibt noch einen weiteren wichtigen Grund, „warum jetzt“. Vor RabbitMQ hatten wir Abhängigkeiten, die üblicherweise als „Speicher“ (PostgreSQL) und „Lese-Beschleuniger“ (Redis) wahrgenommen werden. RabbitMQ fügt eine dritte Klasse hinzu: Vermittler für Nachrichten. Das ist bereits auf minimalem Niveau nützlich, denn ein typisches Backend-Projekt im echten Leben hat oft mindestens eine solche Komponente: entweder RabbitMQ, Kafka oder einen verwalteten Broker in der Cloud. Wir machen den Kurs nicht zu einem Messaging-Track, aber wir zeigen: So sieht eine reife lokale Umgebung aus, die neben DB und Cache auch einen Broker enthält.
Schließlich ist es ein guter Moment für gedankliche Disziplin: Das Hinzufügen einer neuen Abhängigkeit sollte nicht zu „Umschreiben der gesamten Anwendung“ führen. Wir bauen keinen zweiten Service, wir machen keine Microservices, wir führen keinen separaten „Docker-Modus“ des Codes ein. Wir machen genau das, was wir schon früher gemacht haben: einen Dienst in Compose hinzufügen, ein Profil aktivieren und das minimale Szenario prüfen.
2. RabbitMQ als Infrastruktur
Es gibt eine gefährliche Sache, die wir sofort einfangen wollen, bevor sie wegläuft: RabbitMQ kann zwar Teil einer großen Architektur sein (mit Topologien, Exchanges, Routing-Keys, Retries, DLQ, Deduplizierung und philosophischen Debatten „ist das Event-Driven oder nur eine Queue“). Aber dahin gehen wir heute nicht, denn unser Kurs behandelt Docker/Compose als tägliches Werkzeug eines Java-Entwicklers und nicht die Kunst, ein Broker-Schamane zu werden.
In unserem Kontext ist RabbitMQ so etwas wie die „Poststelle“ innerhalb des lokalen Stands. Die Anwendung legt dort einen „Brief“ (eine Nachricht) ab, und jemand holt diesen Brief später ab. Das ist als Lernmodell praktisch, weil es ein Minimum ermöglicht, das die Umgebungsverkabelung prüft: Der Broker startet, die Anwendung verbindet sich, die Nachricht geht raus, die Nachricht kommt an. Fertig. Ohne Fanatismus und ohne „lasst uns ein System wie bei FAANG entwerfen“ (was meistens bedeutet: „lasst uns das Leben kompliziert machen, um es dann heldenhaft zu vereinfachen“).
Es ist auch wichtig, die Projektgrenzen einzuhalten. Unser Container-Ready Catalog Service bleibt eine einzige Spring Boot Anwendung. RabbitMQ zwingt uns nicht, einen zweiten Consumer-Service zu erstellen. Wir können die Nachricht innerhalb derselben Anwendung empfangen (über @RabbitListener) und den Empfang einfach loggen. In einem echten Produkt wären es natürlich oft verschiedene Dienste. Aber hier ist das Ziel ein anderes: Den Compose-Stack und die Konfigurationsdisziplin zu zeigen, nicht aber ein verteiltes System zu bauen.
Um es ganz ehrlich zu sagen: RabbitMQ brauchen wir heute als „noch einen Container, zu dem die Anwendung über den Service-Namen verbinden können muss“. Wir trainieren nicht den Broker, sondern die Fähigkeit, nicht den Überblick zu verlieren, wenn der Stack um einen Dienst wächst.
3. Was am Ende des Tages erreicht sein soll
Hier ist es wichtig, das Ziel nicht zu verwechseln. Das ausreichende Ergebnis heute ist nicht „RabbitMQ vollständig gelernt“, sondern eine sauber eingebaute weitere Abhängigkeit im selben Compose-Stack, ohne das Projekt auf eine neue Architekturspur zu bringen.
Am Ende der Lektion sollten drei Dinge klar sein:
– Wo rabbitmq in compose.yaml lebt und wie die Anwendung es über den Service-Namen findet;
– Wie Messaging als weiterer Laufzeitmodus derselben Spring Boot Anwendung aktiviert wird;
– Anhand welchen minimalen Indikators man sieht, dass die Verbindung tatsächlich funktioniert: Die Nachricht wurde gesendet und ist angekommen – das ist in den Logs sichtbar.
Wenn diese drei Punkte eine einzige Ursache-Wirkungs-Kette bilden, hat die Lektion ihren Zweck erfüllt.
4. Woraus dieser Schritt besteht
Die Reihenfolge ist hier wichtig. Zuerst braucht es den Broker selbst als normalen Compose-Service: einen klaren Namen rabbitmq, normale Ports und eine schnelle Möglichkeit zu prüfen, dass der Container überhaupt lebt. Danach – die Laufzeitkonfiguration der Anwendung: dasselbe Image, aber mit dem messaging-Profil und Verbindungsparametern, nicht ein separates JAR und kein neues Dockerfile.
Erst danach ergibt es Sinn, sich einen kurzen Nachrichtenweg anzusehen: Eine HTTP-Aktion löst den Versand aus, RabbitMQ nimmt die Nachricht an, der Listener empfängt sie, und in den Logs sind beide Punkte sichtbar. Das reicht, um den Stand realistischer zu machen, ohne dass er in einen zweiten Service, einen zweiten Build-Path und eine neue Religion „lasst uns gleich eine Event-Driven-Universum entwerfen“ zerfällt.
5. Typische Fehler bei der Arbeit mit RabbitMQ
Fehler Nr. 1: Erwartung „heute lernen wir RabbitMQ vollständig“.
RabbitMQ ist ein großes Thema, und man kann es monatelang studieren, besonders wenn man anfängt, über Topologie, Zustellgarantien und „wie entwirft man eine Event-Driven-Architektur richtig“ zu lesen. In diesem Kurs ist RabbitMQ eine infrastrukturelle Komponente des Stands. Hält man die Erwartung „minimale Verkabelung und minimaler Austausch“, wird der Stoff viel verständlicher und löst nicht das Gefühl aus „man hat mir etwas vorenthalten“.
Fehler Nr. 2: Versuch, das Projekt in mehrere Services zu verwandeln.
Eine häufige Reaktion auf das Wort „Broker“ ist: „Oh, dann muss ich einen separaten Consumer-Service bauen!“. In der realen Welt ist das oft so, aber in unserem Lernprojekt vergrößert das sofort die Komplexitätsoberfläche: ein zweiter Service, ein zweites Dockerfile, ein zweiter Lifecycle – und man fängt an, Microservices zu lernen statt Compose. Wir bleiben in einer Anwendung und nutzen den Broker als Abhängigkeit.
Fehler Nr. 3: Der Wunsch, „es gleich schön zu machen“ – mehrere Queues, Exchanges und komplexe Nachrichten.
Das sieht nach Vorsorge für die Zukunft aus, zerstört aber tatsächlich die Reihenfolge. Heute müssen wir einen einzigen transparenten Nachrichtenweg sehen. Sobald mehrere Queues, Routing und komplexe Payloads auftauchen, beginnt man, Benennungen und Konfiguration zu debuggen, statt die Compose-Verkabelung.
Fehler Nr. 4: Architekturdebatten führen, bevor der Stand selbst zusammengebaut ist.
An dieser Stelle verfällt man leicht in Diskussionen wie „warum nicht Kafka“, „braucht man Async überhaupt“, „wo bleibt die Event-Driven-Architektur“. Das sind alles interessante Fragen, aber sie helfen Ihnen heute nicht, den Broker in den Compose-Stack einzubauen. Zuerst braucht man eine funktionierende Verkabelung, und erst dann kommen die großen Weltdebatten.
GO TO FULL VERSION