RabbitMQ确保消息到达队列

时间:2019-08-12 15:37:25

标签: rabbitmq spring-amqp spring-rabbitmq

我想确保邮件到达队列。 否则,我要例外。

我尝试过发布者退货,但这不是我所需要的,因为它在不同的线程上,我认为以某种方式在发送消息的线程上等待它会很棘手。

没有事务通道,当不存在交换时,convertAndSend方法会成功返回,而事务通道现在会引发异常。

当没有基于路由键的路由时,我需要的是相同的。

@SpringBootApplication
public class DemoApplication {

    private static final Logger log = Logger.getGlobal();

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Bean
    RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> log.info(replyCode + "," + replyText));
        rabbitTemplate.setChannelTransacted(true);
        rabbitTemplate.setMandatory(true);
        return rabbitTemplate;
    }

    @Bean
    CommandLineRunner commandLineRunner(RabbitTemplate rabbitTemplate) {
        return args -> {
            rabbitTemplate.convertAndSend("exchangeName", "routingKey", "message");
            log.info("Send is done.");
        };
    }
}

仅属性:spring.rabbitmq.publisher-returns = true

春季启动版本:2.1.7.RELEASE

实际

  

不交换-> convertAndSend引发异常

     

交换时没有路线->方法返回

预期

  

不交换-> convertAndSend引发异常

     

交换时没有路由-> convertAndSend引发异常

1 个答案:

答案 0 :(得分:1)

您需要使用发布者确认和关联数据:

spring.rabbitmq.publisher-returns=true
spring.rabbitmq.publisher-confirms=true
spring.rabbitmq.template.mandatory=true
@SpringBootApplication
public class So57464212Application {

    public static void main(String[] args) {
        SpringApplication.run(So57464212Application.class, args);
    }


    @Bean
    public ApplicationRunner runner(RabbitTemplate template) {
        template.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            System.err.println("Returned: " + replyText);
        });
        template.setConfirmCallback((correlationData, ack, cause) -> {
            System.err.println("ack:" + ack);
        });
        return args -> {
            CorrelationData correlationData = new CorrelationData("foo");
            template.convertAndSend("", "NOQUEUE", "bar", correlationData);
            correlationData.getFuture().get(10, TimeUnit.SECONDS);
            if (correlationData.getReturnedMessage() != null) {
                throw new RuntimeException("Message was returned");
            }
        };
    }

}