如果队列不存在,则丢失消息

时间:2017-05-25 08:35:56

标签: rabbitmq spring-rabbit

当我们将消息发送到RabbitMQ并且队列不存在时,消息会丢失而不会丢失任何错误。

邮件将发布到哪里?死队?

2 个答案:

答案 0 :(得分:4)

这就是RabbitMQ的设计方式 - 发布者发布到交易所,而不是队列。

如果没有绑定队列(如果交换需要匹配的路由密钥),则只丢弃该消息。

您可以enable publisher returns并在发布时设置mandatory标志,并且代理将返回消息(但它到达不同的线程,而不是发布线程)。

答案 1 :(得分:1)

您的消息可以返回给您

如果没有队列绑定到交换。要收回它们而不丢失这些消息,您必须执行以下操作:

1。将这些属性添加到您的application.yml

spring:
  rabbitmq:
    publisher-confirm-type: correlated
    publisher-returns: true
    template:
      mandatory: true

2。创建RabbitConfirmCallback

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

@Component
public class RabbitConfirmCallback implements RabbitTemplate.ConfirmCallback {
    private static final Logger logger = LoggerFactory.getLogger(RabbitConfirmCallback.class);

    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack && correlationData != null && correlationData.getId() != null) {

            Message returnedMessage = correlationData.getReturnedMessage();
            String dataId = correlationData.getId();

            if (returnedMessage != null) {
                logger.error("Message wasn't delivered to Consumer; " + returnedMessage + "\nCorrelationData id = " + dataId);
            } else {
                logger.info("CorrelationData with id " + dataId + " acknowledged;");
            }

        } else {
            if (ack) {
                logger.warn("Unknown message acknowledgement received: " + correlationData);
            } else {
                logger.info("Broker didn't accept message: " + cause);
            }
        }
    }
}

将立即尝试在无限制队列的这种交换中发送消息之后触发该回调方法confirm(...) 。 在correlationData对象中,您将找到returnedMessage字段,该字段将是消息的messagePropertiesbody

3。将RabbitConfirmCallback设置为RabbitTemplate

@Autowired
public void post(RabbitTemplate rabbitTemplate, RabbitConfirmCallback rabbitConfirmCallback){
    rabbitTemplate.setConfirmCallback(rabbitConfirmCallback);
}

4。发送邮件时,添加CorrelationDate对象

带有一些唯一的标识符

rabbitTemplate.convertAndSend(exchange, routingKey, wrapMessage(message),
                              new CorrelationData(stringId));