Spring RabbitTemplate-如何在Publisher确认模式下获取已发布的NACK消息

时间:2015-12-07 01:32:05

标签: spring-amqp spring-rabbitmq

我有一个使用spring在RabbitQueue上发布消息的网络应用程序。我已启用Publisher确认并返回已启用,并且我使用的是spring rabbit:template。这是我的配置:

    <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>

我的MessagesConfirmCallback类:

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");
        }       
    }
}

和MessageReturnCallback类:

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());

    }
}

我能够看到MessageReturnCallback.returnedMessage在发布成功并收到ACK的情况下被调用(并且通过查看已发布的有效负载),但不是在NACK的情况下。在NACK的情况下,有没有办法获取已发布的消息?

2 个答案:

答案 0 :(得分:2)

当由于无法路由到队列而返回消息时,RabbitMQ将返回完整的消息。

当消息被激活(或被nacked)时,RabbitMQ只返回一个数字序列,不提供整个消息。 Spring AMQP使用该序列号来确定要返回的相关数据。

应用程序需要在发送之前保留对消息的引用(可能在Map中,由CorrelationData中的某些内容键入,或者甚至在相关数据本身中),以便在相关数据提供时ack / nack,你可以确定它的用途。

答案 1 :(得分:0)

当经纪人给出发布者确认时,不会返回完整的消息,但仅返回相关数据(不要将其误解为correlation_id)。开发人员可以在通过rabbitTemplate.send或rabbitTemplate.convertAndSend将消息发布到代理时传递关联数据,并且传递的关联数据将由代理发回。开发人员可以将关键数据(或封装在关联数据中的id字段)键入地图,或者可以存储在某个数据库中,并可以从那里检索消息。