【问题标题】:Messages lost if queue does not exist如果队列不存在,则消息丢失
【发布时间】:2017-10-25 20:04:05
【问题描述】:

当我们向 RabbitMQ 发送消息时,如果队列不存在,则消息会丢失而不会引发任何错误。

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

【问题讨论】:

    标签: rabbitmq spring-rabbit


    【解决方案1】:

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

    如果没有队列绑定(如果交换需要,则使用匹配的路由键),则简单地丢弃该消息。

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

    【讨论】:

      【解决方案2】:

      您的消息可以退回给您

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

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

      【讨论】:

        猜你喜欢
        • 2010-09-23
        • 2019-08-16
        • 2017-06-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-28
        • 1970-01-01
        相关资源
        最近更新 更多