我有一个使用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的情况下,有没有办法获取已发布的消息?
答案 0 :(得分:2)
当由于无法路由到队列而返回消息时,RabbitMQ将返回完整的消息。
当消息被激活(或被nacked)时,RabbitMQ只返回一个数字序列,不提供整个消息。 Spring AMQP使用该序列号来确定要返回的相关数据。
应用程序需要在发送之前保留对消息的引用(可能在Map中,由CorrelationData
中的某些内容键入,或者甚至在相关数据本身中),以便在相关数据提供时ack / nack,你可以确定它的用途。
答案 1 :(得分:0)
当经纪人给出发布者确认时,不会返回完整的消息,但仅返回相关数据(不要将其误解为correlation_id)。开发人员可以在通过rabbitTemplate.send或rabbitTemplate.convertAndSend将消息发布到代理时传递关联数据,并且传递的关联数据将由代理发回。开发人员可以将关键数据(或封装在关联数据中的id字段)键入地图,或者可以存储在某个数据库中,并可以从那里检索消息。