Nachrichten brauchen eine feste Reihenfolge? Service-Bus-Sessions konfigurieren
Eine Session ist eine Gruppe zusammengehöriger Nachrichten innerhalb einer Queue. Dein Shop hat beispielsweise zwei Bestellungen, A und B. Jede durchläuft Created → Paid → Shipped, aber ihre Updates treffen gemischt ein:
| Eingang | Nachricht | SessionId |
|---|---|---|
| 1 | Bestellung A — Created | A |
| 2 | Bestellung B — Created | B |
| 3 | Bestellung A — Paid | A |
| 4 | Bestellung B — Paid | B |
| 5 | Bestellung A — Shipped | A |
Der Sender setzt SessionId = A für jede Nachricht zu Bestellung A und SessionId = B für jede Nachricht zu Bestellung B. Service Bus gruppiert sie anhand dieser Nachrichteneigenschaft. Eine Bestell-ID im JSON-Inhalt wird nicht automatisch dafür ausgelesen.
Der Sender erstellt oder sperrt die Session nicht separat. Er setzt bei jeder Nachricht einer Bestellung dieselbe SessionId und sendet die Updates in der gewünschten Reihenfolge. Zum Beispiel:
sender.send_messages(ServiceBusMessage("Created", session_id="order-123"))
sender.send_messages(ServiceBusMessage("Paid", session_id="order-123"))
sender.send_messages(ServiceBusMessage("Shipped", session_id="order-123"))
Verwende für eine andere Bestellung eine andere ID, etwa order-456. Service Bus gruppiert die Nachrichten automatisch. Der Empfänger übernimmt die Session-Sperre, wenn er die Session annimmt. Das vorbereitete Skript unten setzt session_id bereits beim Erstellen jeder Nachricht.
Eine Queue, zwei Sessions:
Session A: Created → Paid → Shipped
Session B: Created → Paid
Die Sperre gilt für die gesamte Session, nicht nur für eine Nachricht. Übernimmt Worker 1 die Session A, kann nur dieser Worker ihre Nachrichten empfangen, solange seine Session-Sperre gültig ist. Er verarbeitet und bestätigt Created, dann Paid und anschließend Shipped nacheinander. Worker 2 kann gleichzeitig Session B bearbeiten.
Das Bestätigen einer Nachricht entfernt diese einzelne Nachricht; es gibt nicht die gesamte Session frei. Gibt der Worker die Session frei oder läuft ihre Sperre ab, kann ein anderer Worker die verbleibenden Nachrichten übernehmen.
Ohne Sessions könnten verschiedene Worker Updates derselben Bestellung empfangen und in unterschiedlicher Reihenfolge fertigstellen. Sessions geben einem Worker exklusiven Zugriff auf den Nachrichtenstrom dieser Bestellung. Der Worker muss die Nachrichten trotzdem nacheinander verarbeiten.
Die Reihenfolge gilt innerhalb jeder Session, nicht über alle Bestellungen hinweg. Sessions bewahren die Eingangsreihenfolge; sie sortieren das JSON-Feld step nicht. Sendet der Sender Shipped vor Paid, korrigieren Sessions diesen Fehler nicht.
Verwende deinen Standard-Namespace sb-ctmessagingweu und deine Rolle Azure Service Bus Data Owner aus dem Queue-Trip. Nutze deinen tatsächlichen Namespace-Namen, falls er abweicht. Lass den öffentlichen Netzwerkzugriff für dieses Lab aktiviert.
Der Service Bus Explorer im Portal unterstützt keine Session-Verarbeitung. Wir erstellen die Queue im Portal und führen anschließend eine vorbereitete Python-Datei in Azure Cloud Shell aus. Du brauchst keine VM, keine lokale Installation, keinen Connection String und musst keinen Anwendungscode schreiben.
Queue mit aktivierten Sessions erstellen
Öffne den Namespace → Entities → Queues → + Queue:
Name: orders-sessions
Enable sessions: Enabled
Behalte die übrigen Standardwerte bei und erstelle die Queue. Sessions müssen bei der Erstellung aktiviert werden. Deine vorhandene Queue orders lässt sich nachträglich nicht umstellen. Nutze diese separate Queue für das Experiment.
Screenshot 1: Erstellungsformular von orders-sessions mit ausgewähltem Enable sessions, vor dem Erstellen.

Vorbereitetes Beispiel in Cloud Shell ausführen
Lade das Session-Beispiel herunter. Öffne im Azure-Portal Cloud Shell über die obere Symbolleiste und wähle Bash. Wähle bei der ersten Einrichtung deine Lab-Subscription; eine Sitzung ohne Storage-Konto reicht aus.
Lade über Upload/Download files → Upload in Cloud Shell die Datei service-bus-sessions.py hoch. Führe im Terminal aus:
cd "$HOME"
az account set --subscription 'CloudTrips TEST'
python3 -m venv /tmp/ct-servicebus-sessions
source /tmp/ct-servicebus-sessions/bin/activate
python -m pip install 'azure-servicebus>=7.14,<8' 'azure-identity>=1.17,<2' 'websocket-client>=1.6,<2'
python service-bus-sessions.py --namespace sb-ctmessagingweu
Ersetze sb-ctmessagingweu, falls dein Namespace anders heißt. Das Skript nutzt deine Azure-CLI-Anmeldung in Cloud Shell und sendet sechs Nachrichten über eine verschlüsselte WebSocket-Verbindung. Seine Bibliotheken werden nur in der temporären Cloud-Shell-Umgebung installiert.
Die Sendereihenfolge ist absichtlich verschachtelt:
SENT CT-3001 1 Created
SENT CT-3002 1 Created
SENT CT-3001 2 Paid
SENT CT-3002 2 Paid
SENT CT-3001 3 Shipped
SENT CT-3002 3 Shipped
Jede Bestellung hat ihre eigene SessionId. Ein neuer Präfix pro Durchlauf trennt wiederholte Tests. Das Skript übernimmt anschließend zuerst die Session von CT-3002, empfängt jeweils eine Nachricht, prüft Reihenfolge und Inhalt und bestätigt sie, bevor es die nächste empfängt. Danach wiederholt es dies für CT-3001.
Tatsächliche Verarbeitungsreihenfolge prüfen
Nach den SENT-Zeilen erwartest du diese Ausgabe:
PROCESSED CT-3002 1 Created
PROCESSED CT-3002 2 Paid
PROCESSED CT-3002 3 Shipped
PASS CT-3002: 1 -> 2 -> 3
PROCESSED CT-3001 1 Created
PROCESSED CT-3001 2 Paid
PROCESSED CT-3001 3 Shipped
PASS CT-3001: 1 -> 2 -> 3
PASS: both sessions processed in order; six messages completed.
Das Programm prüft die empfangenen Nachrichteninhalte und sortiert sie nicht vor der Anzeige. Ein fehlender oder unerwarteter Schritt löst einen Fehler aus, statt einen erfolgreichen Test zu melden.
Screenshot 2: Cloud Shell mit beiden Bestellungen in der Reihenfolge 1 → 2 → 3 und dem abschließenden PASS-Ergebnis.

CT-3002 wird zuerst fertig, weil das Skript diese Session ausdrücklich zuerst auswählt. Die beiden Bestellungen haben also unabhängige Abläufe. Dieses kleine Beispiel nutzt jeweils einen Empfänger; ein echter Dienst kann verschiedene Sessions parallel verarbeiten.
Kehre zu orders-sessions → Overview zurück und aktualisiere die Ansicht. Nach einem erfolgreichen Lauf auf einer neuen Queue sollte Active messages wieder 0 anzeigen. Der Zähler kann sich etwas verzögert aktualisieren.
Screenshot 3: Übersicht der Queue orders-sessions mit null aktiven Nachrichten nach dem erfolgreichen Lauf.

Wenn das Beispiel fehlschlägt
- Zugriff verweigert: Prüfe, ob dem Cloud-Shell-Benutzer Azure Service Bus Data Owner auf Namespace-Ebene zugewiesen ist. Eine neue Zuweisung kann einige Minuten benötigen.
- Queue- oder Session-Fehler: Kontrolliere Namespace-Namen, Existenz von orders-sessions und die Aktivierung der Sessions bei der Erstellung.
- Sperre abgelaufen oder Lauf unterbrochen: Die Demo erneuert keine Sperren für lange Verarbeitungen. Starte sie erneut für ein frisches Session-Paar. Nachrichten eines fehlgeschlagenen Laufs bleiben in ihren früheren Sessions, sodass die Gesamtzahl über null liegen kann. Lösche und erstelle ausschließlich die dedizierte Lab-Queue orders-sessions neu, wenn du einen sauberen Neustart möchtest.
Sessions garantieren keine genau einmal ausgeführten Geschäftsaktionen. Nach einem Fehler kann eine Nachricht erneut zugestellt werden. Ein produktiver Worker braucht weiterhin Duplikatbehandlung, die Erneuerung der Session-Sperre bei langen Aufgaben und eine Regelung für fehlgeschlagene Schritte, bevor spätere Geschäftsschritte fortgesetzt werden.
Abschluss
Behalte den Namespace für spätere Messaging-Trips. Nach den Screenshots kannst du orders-sessions löschen. Schließe Cloud Shell nach Abschluss; die temporäre Umgebung kann verworfen werden. Lösche die Lab-Ressourcengruppe, sobald du den Standard-Namespace nicht mehr brauchst. Auch für einen leeren Namespace fallen weiterhin Grundgebühren an.