Spring RabbitTemplate- How to get hold of the published message for NACKs in Publisher confirm mode

自闭症网瘾萝莉.ら 提交于 2020-02-04 02:34:22

问题


I have a web-app that posts messages on RabbitQueue using spring. I have turned on Publisher confirms and returns enabled and I'm using spring rabbit:template. This is my configuration:

    <rabbit:template id="amqpTemplate" connection-factory="amqpConnectionFactory" retry-template="retryTemplate" confirm-callback="messagesConfirmCallback" return-callback="messagesReturnCallback"   
    exchange="${rabbitmq.rest.exchange}" routing-key="key.listener" mandatory="true" />

<rabbit:connection-factory id="amqpConnectionFactory" publisher-confirms="true" publisher-returns="true"  connection-factory="secureClientConnectionFactory" />

<bean id="messagesConfirmCallback" class="com.test.message.MessagesConfirmCallback" />
<bean id="messagesReturnCallback" class="com.test.message..MessagesReturnCallback" />

<bean id="secureClientConnectionFactory" class="org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean"  >
    <property name="uri" value="${mq.uri}" />
</bean>

My MessagesConfirmCallback class:

public class MessagesConfirmCallback implements RabbitTemplate.ConfirmCallback {

    private static final Log LOGGER = LogFactory.getLog(MessagesConfirmCallback.class);

    @Override
    public void confirm(CorrelationData correlationData, boolean ack,
            String cause) {
        if(ack){
             LOGGER.info("ACK received");
        }
        else{
            LOGGER.info("NACK received");
        }       
    }
}

and the MessageReturnCallback class:

public class MessageReturnCallback implements RabbitTemplate.ReturnCallback {

    private static final Log LOGGER = LogFactory.getLog(MessagesReturnCallback.class);


    @Override
    public void returnedMessage(Message message, int replyCode,
            String replyText, String exchange, String routingKey) {

        LOGGER.info("Message: " + message.getBody());

    }
}

I am able to see that the MessageReturnCallback.returnedMessage getting invoked (and there by see the published payload) in cases where the publish is successful and ACK is received, but not in case of NACK. Is there a way to get hold of the published message in cases of NACK?


回答1:


When a message is returned because it can't be routed to a queue, RabbitMQ returns the complete message.

When a message is acked (or nacked), RabbitMQ just returns a sequence a number, the whole message is not supplied. Spring AMQP uses that sequence number to determine which correlation data to return.

The application needs to keep a reference to the message before sending (perhaps in a Map, keyed by something in the CorrelationData, or even in the correlation data itself) so that when the correlation data is supplied in the ack/nack, you can determine which message it is for.




回答2:


When publisher confirm is given by the broker the complete message is not returned but only a correlation data is returned (don't misinterpret it as correlation_id). Developer can pass correlation data when publishing message to broker via rabbitTemplate.send or rabbitTemplate.convertAndSend and the passed correlation data will be sent back by broker. And developer can make a map keyed on correlation data(or id field encapsulated in correlation data) or can store in some database and can retrieve message from there.



来源:https://stackoverflow.com/questions/34125116/spring-rabbittemplate-how-to-get-hold-of-the-published-message-for-nacks-in-pub

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!