无法使用SprintBoot在RabbitMQ中解密消息

时间:2017-08-25 07:40:14

标签: java spring-boot rabbitmq spring-rabbit spring-rabbitmq

我有以下Consumer类,它侦听队列中的传入消息,然后确认并确认它们。 ack部分工作正常,但nack无效。由于某种原因,所有消息都被激活了。

application.properties

spring.rabbitmq.host=192.168.99.100
spring.rabbitmq.port=5677
spring.rabbitmq.username=abc
spring.rabbitmq.password=def
spring.rabbitmq.listener.acknowledge-mode=manual

Producer.java

@Component
public class Producer implements CommandLineRunner {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private Queue queue;

    @Override
    public void run(String... args) throws Exception {
        for (int i = 0; i < 100; i++) {
            this.rabbitTemplate.convertAndSend(this.queue.getName(), "Hello World !");
        }
    }

}

Consumer.java

@Component
public class Consumer {

    private final CountDownLatch latch = new CountDownLatch(1);
    int ctr = 0;

    @RabbitListener(queues = "producer-consumer-nack2.q")
    public void receiveQueue(String text, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException, InterruptedException {
        ctr++;
        //nack every 10th, 20th, 30th and so on message 
        if (ctr % 10 == 0) {
            System.out.println("Nack Message #" + ctr + ": " + text);
            channel.basicNack(tag, false, true);
        } else {
            System.out.println("Ack Message #" + ctr + ": " + text);
            channel.basicAck(tag, true);
        }
        latch.countDown();
    }

    public CountDownLatch getLatch() {
        return latch;
    }

}

由于消耗了所有消息,队列为空(见下文)。 enter image description here

1 个答案:

答案 0 :(得分:2)

我相信nack的工作方式是它会拒绝然后将消息排队以便在队列中的同一点重新传递。 (参见rabbitmq文档here

因此,当您查看处理结束时,它将被拒绝,然后再进行重新处理。

我建议调试代码,在你的nack条件(或打印)中使用断点来查看它是否命中了该代码块。然后,如果您在nack之后但在下一次处理消息之前进行调试并检查您的队列 - 我认为您会看到一条消息。