2016-04-18 3 views
0

Ich versuche, Probe Retry-Mechanismus für RabbitMQ mit Spring StatefulRetryOperationsInterceptor zu implementieren.Wie benutze MessageKeyGenerator in StatefulRetryOperationsInterceptor

Wie in der Dokumentation angegeben, muss ich den Nachrichtenschlüsselgenerator einrichten, da die Nachrichten-ID nicht vorhanden ist. Was ich nicht verstehe, ist die tatsächliche Verwendung einer eindeutigen ID, die pro Nachricht generiert wird. das heißt, wenn ich unten Implementierung verwenden ich hatte kein Problem mit Wiederholungs:

StatefulRetryOperationsInterceptor interceptor = 
RetryInterceptorBuilder.stateful() 
      .maxAttempts(3) 
      .backOffOptions(2000, 1, 2000) 
      .messageKeyGenerator(
      new MessageKeyGenerator() { 
       @Override 
       public Object getKey(Message message) { 
       return 1; 
       } 
      ); 
container.setAdviceChain(new Advice[] {interceptor}); 

Antwort

1

Stateful Wiederholungs muss die Ursprungsnachricht irgendwie einzigartig sein - so das Wiederholungs „Zustand“ für die Nachricht bestimmt werden kann - der einfachste Weg ist, Der Nachrichtenverleger muss einen eindeutigen Nachrichten-ID-Header hinzufügen.

Es ist jedoch möglich, dass etwas in Ihrem Nachrichtentext oder einer anderen Kopfzeile verwendet wird, um die Nachricht eindeutig zu identifizieren. Geben Sie MessageKeyGenerator ein, um die eindeutige ID zu ermitteln.

Die Verwendung einer Konstante (1 in Ihrem Fall) funktioniert nicht, da jede Nachricht den gleichen Nachrichtenschlüssel hat und alle als Lieferungen derselben Nachricht betrachtet werden (aus einer Wiederholungs-Perspektive).

Das Framework bietet eine MissingMessageIdAdvice, die eingeschränkte Unterstützung für stateful retry bieten kann (wenn sie vor dem Wiederholungsrat der Advice-Kette hinzugefügt wurde). Es fügt der eingehenden Nachricht eine messageId hinzu.

"Eingeschränkt" bedeutet, dass die vollständige erneute Statuswiederherstellung nicht verfügbar ist - nur ein erneuter Zustellversuch ist zulässig.

Wenn die erneute Zustellung fehlschlägt, wird die Nachricht zurückgewiesen, was dazu führt, dass sie verworfen oder an den DLX/DLQ weitergeleitet wird, wenn sie so konfiguriert ist. In allen Fällen wird der "temporäre" Zustand aus dem Cache entfernt.

Im Allgemeinen, wenn volle Wiederholungsunterstützung benötigt wird und es keine messageId Eigenschaft gibt und es keine Möglichkeit gibt, einen eindeutigen Schlüssel mit einer MessageKeyGenerator zu generieren, würde ich stateless retry empfehlen.

+0

Hallo Gary, Danke für deine Antwort. Ich kann eindeutige ID pro Nachricht mit MessageKeyGenerator generieren. Aber ich wollte testen, ob die Wiederholung funktioniert, wenn die gleiche ID für alle Nachrichten verwendet wird, und ich habe festgestellt, dass die Wiederholung für alle Nachrichten funktioniert. Also, ich verstehe immer noch nicht Notwendigkeit für eine eindeutige ID. Können Sie bitte helfen? Danke noch einmal. –

+0

Sie werden kein Problem haben, wenn die Container-Parallelität "== 1" ist, da jede Zustellung im selben Thread stattfindet und die Wiederholungen für eine Nachricht erschöpft sind, bevor die nächste verarbeitet wird. Sobald Sie die Parallelität erhöhen, werden mehrere Nachrichten an verschiedene Threads übermittelt. Wenn sie alle den gleichen Nachrichtenschlüssel haben, funktioniert die Wiederholung nicht ordnungsgemäß. Bei einer erfolgreichen Zustellung wird der Status zurückgesetzt, sodass eine ungültige Nachricht häufiger als erwartet wiederholt wird. –

+0

Danke Gary, hab es jetzt :) Prost. –