如何配置RabbitMQ(在Spring Boot 2.x中)以便手动确认起作用

时间:2019-02-06 13:03:31

标签: spring spring-boot rabbitmq spring-rabbitmq

所以我阅读了所有示例,我有com.rabbitmq.client.Channel和@Header(AmqpHeaders.DELIVERY_TAG),但是当我尝试调用Channel.basicNack(long deliveryTag,boolean multiple,boolean requeue)时,结果是“ java.lang.IllegalStateException:通道已关闭;无法确认/否定”。我可以看到CachingConnectionFactory不支持任何确认方法。所以我的问题是,我必须使用什么ConnectionFactory以及如何对其进行配置,以便basicAck / basicNack起作用?

Spring Boot版本2.1.0.RELEASE application.yaml:

spring:
  rabbitmq:
    host: ${RABBITMQ_HOST:localhost}
    port: ${RABBITMQ_PORT:5672}
    username: ${RABBITMQ_USERNAME:guest}
    password: ${RABBITMQ_PASSWORD:guest}
    listener:
      type: simple
      simple:
        acknowledge-mode: manual

配置类:

@EnableRabbit
@Configuration
public class RabbitMqConfig implements RabbitListenerConfigurer {

@Value("${app.rabbitmq.incoming-queue}")
private String incomingQueue;

private AmqpAdmin amqpAdmin;

@Autowired
public RabbitMqConfig(AmqpAdmin amqpAdmin) {

    this.amqpAdmin = amqpAdmin;
}

@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {

    RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
    rabbitTemplate.setChannelTransacted(true);
    rabbitTemplate.setMessageConverter(jsonMessageConverter());
    return rabbitTemplate;
}

@Bean
MessageConverter jsonMessageConverter() {
    return new Jackson2JsonMessageConverter();
}

@Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar registar) {
    registar.setMessageHandlerMethodFactory(createDefaultMessageHandlerMethodFactory());
}

@Bean
public DefaultMessageHandlerMethodFactory createDefaultMessageHandlerMethodFactory() {

    DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
    factory.setMessageConverter(new MappingJackson2MessageConverter());
    return factory;
}

@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
        ConnectionFactory connectionFactory, CommonAmqpErrorHandler commonAmqpErrorHandler) {

    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    factory.setMessageConverter(jsonMessageConverter());
    factory.setErrorHandler(commonAmqpErrorHandler);

    return factory;
}

@PostConstruct
public void afterInit() {

    amqpAdmin.declareQueue(new Queue(getDeadLetterQueueName(incomingQueue), true));
    amqpAdmin.declareQueue(
            QueueBuilder.durable(incomingQueue).withArgument("x-dead-letter-exchange", "")
                    .withArgument("x-dead-letter-routing-key",
                            getDeadLetterQueueName(incomingQueue)).build());
}

private String getDeadLetterQueueName(String queueName) {
    return queueName + ".dead-letter.queue";
}
}

侦听器代码:

@Transactional(rollbackOn = Exception.class)
@RabbitListener(queues = "${app.rabbitmq.incoming-queue}", errorHandler = "notificationListenerErrorHandler")
public void onMessage(@Valid @Payload NotificationDto notification, Message message,
        Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
    System.out.println("00000 > " + tag);
    System.out.println("11111");
    channel.basicNack(tag, false, true);
    System.out.println("222222");
}

1 个答案:

答案 0 :(得分:0)

从头开始,发现

@Transactional(rollbackOn = Exception.class)

引起了问题。如果我删除它,就可以了