【问题标题】:How to consume message from RabbitMQ dead letter queue one by one如何从 RabbitMQ 死信队列中一一消费消息
【发布时间】:2020-08-30 21:26:14
【问题描述】:

要求就像通过暴露一个REST服务API(Spring Boot)来处理来自死信队列的消息。 这样一旦调用了 REST 服务,就会从 DL 队列中消费一条消息,并再次发布到主队列中进行处理。 @RabbitListener(queues = "QUEUE_NAME") 立即使用消息,根据场景,这不是必需的。该消息只需要由 REST 服务 API 使用。 有什么建议或解决方案吗?

【问题讨论】:

    标签: spring-boot rabbitmq spring-amqp


    【解决方案1】:

    如果您使用的是 Spring;您可以使用RabbitTemplate.receive(...) 避免其他答案中的所有样板。

    编辑

    要手动确认/拒绝消息,请改用execute 方法。

    template.execute(channel -> {
        GetResponse got = channel.basicGet("foo", false);
    
        // ...
    
        channel.basicAck(got.getEnvelope().getDeliveryTag(), false);
    
        return null;
    });
    

    它的级别有点低,但同样,大部分样板文件都会为您处理。

    【讨论】:

    • @Autowired 私有 RabbitMQService rabbitMQService;消息消息 = rabbitTemplate.receive(QUEUE_NAME);有什么方法可以使用deliveryTag 确认频道?
    • 使用 execute() 而不是 receive() - 请参阅我的答案的编辑。
    【解决方案2】:

    我不认为RabbitListener 在这里会有所帮助。

    但是您可以手动实现此行为。

    Spring Boot 会自动创建RabbitMq 连接工厂,以便您可以使用它。当进行 http 调用时,只需手动从队列中读取一条消息,您可以使用 basic.get 同步获取一条消息:

    @Autowire 
    private ConnectionFactory factory 
    
    void readSingleMessage() {
       Connection connection = null;
       Channel channel = null;
       try {
          connection = factory.newConnection();
          channel = connection.createChannel();
    
          channel.queueDeclare(QUEUE_NAME, true, false, false, null);
    
          GetResponse response = channel.basicGet(QUEUE_NAME, true);
          if (response != null) {
             //Do something with the message
          }
       } finally {
         //Check if not null
         channel.close();
         connection.close();
       }
    
    }
    

    【讨论】:

    • 使用 Spring 时,您可以使用 RabbitTemplate.receive(...) 避免所有样板文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-22
    • 2012-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多