Start / Seminare / Quarkus für Spring-Boot-Teams
Modul
Messaging und externe Systeme
4 Kapitel in diesem Modul-Video · Laufzeit
Transkript
Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.
Messaging und externe Systeme
0:00 Messaging ist der Teil einer Migration, der beide Welten gleichzeitig am Leben hält. Ein Endpunkt wird umgestellt und ist danach umgestellt — fertig. Ein Kanal dagegen verbindet Dienste, die zu unterschiedlichen Zeitpunkten migriert werden. Genau deshalb lohnt sich hier die meiste Sorgfalt: Sie bauen nicht nur eine neue Verarbeitung, Sie planen einen Übergangszustand, der Wochen oder Monate dauern kann.
0:23 Wir sehen uns das Programmiermodell an, die Frage der Zuverlässigkeit und die Koexistenz beider Welten.
Messaging und externe Systeme
0:30 Mit diesem Modul schließen wir den zweiten Tag ab. Danach läuft Pfandkreis auf Quarkus — mit Persistenz, Tests, Infrastruktur, Security und Messaging. Am dritten Tag geht es dann nicht mehr um Übertragung, sondern um Betrieb: Resilienz, Observability, Container, Native Image und die eigentliche Migrationsstrategie.
Spring for Apache Kafka und Quarkus Messaging
0:50 Beginnen wir mit dem Programmiermodell. Wer mit Listenern und einem Template gearbeitet hat, muss hier umdenken — nicht viel, aber an einer entscheidenden Stelle. Quarkus setzt auf SmallRye Reactive Messaging, das die MicroProfile-Spezifikation umsetzt. Statt eines Listeners gibt es Kanäle: Eine Methode empfängt aus einem Kanal, eine andere sendet in einen Kanal.
1:12 Das Bild: Sie abonnieren keine Zeitung bei einem bestimmten Verlag, sondern stellen einen Briefkasten auf und sagen an anderer Stelle, was hineinkommen soll. Der Vorteil ist, dass der Code nicht mehr weiß, woher die Nachrichten stammen — für Tests und für einen Wechsel des Brokers ist das Gold wert. Hier sehen Sie den entscheidenden Unterschied zu Spring: Das Topic steht nicht im Code, sondern in der Konfiguration. Im Code steht nur der Kanalname.
1:38 Damit lässt sich ein Topic je Umgebung ändern, ohne etwas neu zu übersetzen — und im Test lässt sich derselbe Kanal auf eine völlig andere Quelle legen. Merken Sie sich das Namensmuster: eingehend und ausgehend werden getrennt, und der Teil in der Mitte ist genau der Kanalname aus Ihrem Code. Wenn diese beiden Namen auseinanderlaufen, passiert gar nichts — und das ist die häufigste Startschwierigkeit.
2:02 Ihre Umrechnungstabelle für die Übung. Die ersten beiden Zeilen sind reine Übersetzung. Die dritte ist die inhaltliche Änderung, über die wir eben gesprochen haben. Die vierte betrifft die Metadaten: Wenn Sie mehr brauchen als die Nutzlast — Offset, Zeitstempel, Header —, arbeiten Sie mit dem Nachrichtenobjekt statt direkt mit dem Inhalt.
2:20 Und die Fußnote ist praktisch die wichtigste Zeile der Folie: Datenbankzugriffe in der Verarbeitung müssen als blockierend markiert werden, sonst halten sie einen Thread an, der niemals blockieren darf. Die ersten drei Punkte sind Startschwierigkeiten, die jeweils eine halbe Stunde kosten, wenn man sie nicht kennt: Das Topic wird im Code gesucht, die blockierende Verarbeitung ist nicht markiert, der Kanalname passt nicht zum Konfigurationsschlüssel.
2:45 Der vierte ist gravierender und betrifft genau die Koexistenz, um die es später geht: Wenn die neue Variante dieselbe Gruppen-Kennung benutzt wie die alte, dann teilen sich beide die Nachrichten. Jede Nachricht geht dann entweder an die alte oder an die neue Verarbeitung — was fast nie das ist, was man will.
Zuverlässigkeit in der Verarbeitung
3:02 Damit zur eigentlichen Frage jedes Messaging-Systems: Was passiert, wenn eine Nachricht nicht verarbeitet werden kann? Der Connector kennt drei Strategien. Die Vorgabe hält die Anwendung an — radikal, aber ehrlich: nichts geht verloren, jemand muss sich kümmern. Die zweite protokolliert und macht weiter, was bedeutet, dass Nachrichten verschwinden. Die dritte schreibt den Datensatz in ein eigenes Topic zur Nachsicht.
3:28 Dazu kommt die Frage, wann Offsets bestätigt werden. Wichtig ist, dass Sie diese Entscheidung bewusst treffen — die Vorgabe ist nicht falsch, aber sie bedeutet, dass eine kaputte Nachricht Ihren Dienst anhält. Lesen Sie die drei oberen Zeilen als Abwägung zwischen Verfügbarkeit und Vollständigkeit. Anhalten heißt: maximale Vollständigkeit, minimale Verfügbarkeit.
3:50 Ignorieren heißt das Gegenteil — und ist fast immer die falsche Wahl, weil Datenverlust selten die günstigere Störung ist. Die Dead Letter Queue ist der Kompromiss: Der Dienst läuft weiter, die Nachricht ist aufgehoben. Aber, und das ist die Bedingung: Jemand muss hineinschauen. Eine Dead Letter Queue ohne zuständige Person ist nur ein aufgeräumter Datenverlust.
4:12 Die unterste Zeile betrifft die Bestätigung der Offsets — sie entscheidet darüber, was nach einem Neustart erneut kommt. Der Kern in einem Satz: Datenbankschreiben und Offset-Bestätigung sind zwei getrennte Vorgänge, und zwischen ihnen kann ein Prozess sterben. Dann wird nach dem Neustart dieselbe Nachricht erneut gelesen — und die Rücknahme wäre zweimal gutgeschrieben.
4:34 Das ist kein exotischer Ausnahmefall, das passiert bei jedem Deployment mit ungünstigem Zeitpunkt. Die Lösung ist unspektakulär: ein fachlicher Schlüssel je Nachricht, mit dem sich eine Wiederholung erkennen lässt. Wichtig ist nur, dass Sie es einmal ausprobieren, statt es anzunehmen. Der erste Punkt ist eine Betriebsstörung mit Ansage: Die Vorgabe bleibt stehen, und eine einzige kaputte Nachricht legt den Dienst dauerhaft still — auch nach jedem Neustart wieder.
5:02 Der zweite ist die eben erwähnte herrenlose Dead Letter Queue. Der dritte ist der Klassiker: Idempotenz wird behauptet, nicht geprüft. Und der vierte betrifft die Wiederholungslogik: Ein Fehler, der deterministisch ist — ein ungültiges Format etwa —, wird durch Wiederholung nie besser. Wiederholen hilft bei vorübergehenden Störungen, nicht bei falschen Daten.
Koexistenz während der Migration
5:23 Jetzt der Teil, der Messaging von den anderen Modulen unterscheidet: Beide Welten laufen eine Zeit lang gleichzeitig — und das muss geplant sein. Solange Spring- und Quarkus-Dienste denselben Broker benutzen, entscheidet das Nachrichtenformat über die Verträglichkeit. Das ist die gute Nachricht: Sie können kanalweise migrieren, sofern Serialisierung, Schlüssel und Schema unverändert bleiben.
5:46 Das Bild: Solange alle dieselbe Sprache sprechen, ist es egal, aus welchem Land der Absender kommt. Das Format wird damit zum eigentlichen Vertrag — und Verträge ändert man nicht nebenbei, während man gleichzeitig die Implementierung austauscht. Und weil das Format zum Vertrag wird, gilt dieselbe Disziplin wie bei einer REST-Schnittstelle: Es gibt genau einen, der es ändern darf, und Änderungen sind rückwärtskompatibel — oder sie sind ein eigenes Vorhaben.
6:12 Zwei Reihenfolgen, und ich empfehle die linke. Wenn Sie den Consumer zuerst migrieren, bleibt die Erzeugung unverändert — das Format kann gar nicht abweichen, weil niemand daran gerührt hat. Und der Rückweg ist einfach: Die alte Verarbeitung übernimmt wieder. Beim Producer zuerst haben Sie sofort alle Abnehmer im Spiel, und jede Formatabweichung trifft alle gleichzeitig.
6:34 Es gibt Gründe, trotzdem rechts anzufangen — etwa wenn der Producer der einfachere Dienst ist. Dann aber bitte mit strikter Rückwärtskompatibilität. Vier Verabredungen, die vor dem ersten Kanal stehen sollten. Erstens: Für jede Nachricht ist festgelegt, welches Format gilt und wer es ändern darf. Zweitens die Änderungsregel — Felder ergänzen ist erlaubt, umbenennen und entfernen nicht.
6:58 Drittens bekommt jeder umgestellte Kanal ein Rückfallverfahren, und zwar eines, das jemand schon einmal ausprobiert hat. Und viertens: Der Umschaltzeitpunkt wird verabredet und nicht dem Zufall des nächsten Deployments überlassen. Das klingt bürokratisch — es sind zwanzig Minuten Absprache, die im Störungsfall Stunden sparen.
7:19 Der erste Punkt ist der schon erwähnte Gruppen-Konflikt, und er ist besonders tückisch, weil scheinbar alles funktioniert: Beide Varianten laufen, beide verarbeiten — nur eben jeweils die Hälfte. Der zweite ist die verbotene Formatänderung, und der alte Abnehmer liest still einen Leerwert. Der dritte ist der Wunsch nach dem großen Wurf: alle Kanäle gleichzeitig.
7:39 Und der vierte ist die Abkürzung, die den Rückweg abschneidet — der alte Consumer wird abgeschaltet, bevor der neue sich bewährt hat.
Übung
7:47 In der Übung ziehen wir einen einzigen Kanal um — und lassen den Producer bewusst, wo er ist. Drei Erfolgskriterien, und alle drei sind Verhaltenstests: Die Verarbeitung läuft vollständig, eine fehlerhafte Nachricht landet in der Dead Letter Queue, und eine doppelt zugestellte Nachricht erzeugt keine zweite Buchung. Genau diese drei Punkte werden in der Praxis behauptet und selten geprüft.
8:11 Der Kafka-Dev-Service nimmt Ihnen die Infrastruktur ab, sodass Sie sich auf die Verarbeitung konzentrieren können — der Producer darf ein simpler Testaufruf bleiben. Und noch ein Hinweis zur Bewertung: Ein Test, der nur zeigt, dass gültige Nachrichten verarbeitet werden, beweist über die Migration wenig. Die Aussagekraft steckt vollständig in den beiden Fehlerfällen.
8:32 Die Schritte vier und fünf sind der eigentliche Inhalt der Übung. Eine fehlerhafte Nachricht einspielen und schauen, wo sie landet. Dieselbe Nachricht erneut einspielen und schauen, ob eine zweite Buchung entsteht. Alles davor ist Vorbereitung. Und beachten Sie die Fußnote — die Gruppen-Kennung der neuen Variante bewusst wählen.
8:50 Wenn Sie hier nachlässig sind, streiten sich alte und neue Verarbeitung um die Offsets, und Sie verbringen den Nachmittag mit der Suche nach einem Fehler, den Sie selbst eingebaut haben. Der erste Punkt ist die häufigste Schwäche von Messaging-Tests: Es werden nur gültige Nachrichten geschickt. Damit ist genau der Fall ungeprüft, für den die ganze Fehlerbehandlung existiert. Der zweite ist die Behauptung statt des Nachweises bei der Idempotenz.
9:16 Der dritte ist die Dead Letter Queue ohne Publikum — legen Sie im selben Atemzug fest, wer hineinschaut und wie oft. Und der vierte ist eine typische Unachtsamkeit im Übergangszustand: Der alte Consumer läuft weiter mit, und beide verarbeiten dieselben Nachrichten.
Lieber mit Trainer? Dieses Modul ist Teil unserer Team-Schulungen — mit Übungen, Ihrem eigenen Code und Fragen, die ein Video nicht beantwortet. Mehr erfahren →