So fordern Sie über Spring eine Nachricht an die Rückseite einer Rabbit MQ-Warteschlange an

Nov 20 2020

Ich schreibe einen SpringBoot RabbitMQ Consumer und muss gelegentlich eine Nachricht an die Rückseite der Warteschlange zurückstellen

Ich dachte, so funktioniert die negative Bestätigung, aber ich basicReject(deliveryTag, true)platziere die Nachricht einfach so nah wie möglich an ihrer ursprünglichen Position in der Warteschlange, die sich in meinem Einzelfall direkt an der Vorderseite der Warteschlange befindet.

Mein erster Gedanke war, eine Warteschlange für tote Briefe zu verwenden, die in einem bestimmten Zeitintervall in die Nachrichtenwarteschlange zurückgeführt wird ( ähnlich dem in dieser Antwort erwähnten Ansatz ), aber ich würde lieber keine zusätzliche Warteschlange erstellen, wenn es eine Möglichkeit gibt, die Warteschlange einfach erneut in die Warteschlange zu stellen ZURÜCK der ursprünglichen Warteschlange

Meine folgende Struktur verbraucht die Nachricht einfach und kann sie nicht erneut zur Warteschlange hinzufügen.

Wie kann dies ohne DLQ erreicht werden?

@ServiceActivator(inputChannel = "amqpInputChannel")
    public void handle(@Payload String message,
                       @Header(AmqpHeaders.CHANNEL) Channel channel,
                       @Header(AmqpHeaders.DELIVERY_TAG) Long deliveryTag){

    try{

        methodThatThrowsRequeueError();
        methodThatThrowsMoveToErrorQueueError();

    } catch (RequeueError re) {

        channel.basicAck(deliveryTag, false);
        sendMessageToBackOfQueue(message);
        return;

    } catch (MoveToErrorQueueError me) {
        //Structured the same as sendMessageToBackOfQueue, works fine
        moveMessageToErrorQueue(message);
    }
    
    channel.basicAck(deliveryTag, false);
}

private void sendMessageToBackOfQueue(String message) {
        try {
            rabbitTemplate.convertAndSend(
                exchangeName,
                routingKeyRequeueMessage,
                message,
                message -> {
                    message.getMessageProperties().setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN);
                    return message;
                }
            );
        } catch (AmqpException amqpEx) {
            //error handling which is not triggered...
        }
    }

Antworten

DapperDan Nov 25 2020 at 01:48

TL; DR : Ich habe keine Möglichkeit gefunden, eine Nachricht von einem Abhördienst ohne Zwischenhändler zurück in die Ursprungswarteschlange weiterzuleiten.

Es gibt verschiedene Optionen, die sich um Dead Letter Queues / Dead Letter Exchanges drehen, aber eine Nicht-DLQ / DLX-Lösung, die wir gefunden haben, war ein zeitgesteuerter Austausch, ein Pseudo-DLX, wenn Sie so wollen. Im Wesentlichen:

Die Nachricht wird in MessageExchange (MsgX) eingegeben, das an die Service Queue (SvcQ) weitergegeben wird. Der Dienst (Svc) erhält eine Nachricht vom SvcQ.

Sobald Sie festgelegt haben, dass die Nachricht an die Rückseite des SvcQ gesendet werden soll, sollte Svc:

  1. Senden Sie eine Bestätigung an SvcQ.
  2. Senden Sie die Nachricht an eine andere Vermittlungsstelle, unseren zeitgesteuerten Pseudo-DLX
  3. Der Pseudo-DLX kann so konfiguriert werden, dass Nachrichten in einem bestimmten Zeitintervall an den (BACK OF !!) SvcQ gesendet werden