RabbitHandler 在 Spring 中创建消费者并重试致命异常以用于侦听 RabbitMQ 的队列 [英] RabbitHandler to create consumer and retry on Fatal Exception in Spring for queue on listening to RabbitMQ

查看:86
本文介绍了RabbitHandler 在 Spring 中创建消费者并重试致命异常以用于侦听 RabbitMQ 的队列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Spring AMQP RabbitHandler 并编写了以下代码:

I am using Spring AMQP RabbitHandler and have written the following code:

@RabbitListener(queues = "#{testQueue.name}")
public class Tut4Receiver {

  @RabbitHandler
  public void receiveMessage(String message){
       System.out.println("Message received "+message);
  }
}

队列定义如下:-

@Bean
public Queue testQueue() {
    return new AnonymousQueue();
}

我使用单独的代码来初始化连接工厂.

I am using separate code to initialize the Connection Factory.

我的问题是,如果 RabbitMQ 停机一段时间,它会继续重试创建消费者,但前提是它收到 ConnectionRefused 错误.但是假设该用户在 RabbitMQ 中不存在,并且存在将创建新用户的间隙,那么它会收到来自 RabbitMQ 的致命错误并且它永远不会重试,因此结果是将在 RabbitMQ 上创建自动删除队列而没有任何消费者.

My question is if RabbitMQ is down for some time, it keeps on retrying to create a consumer but only if it receives a ConnectionRefused error. But suppose the user does not exist in RabbitMQ and there is a gap in which a new user will be created, then it receives a fatal error from RabbitMQ and it never retries due to which the result is auto delete queue would be created on RabbitMQ without any consumers.

堆栈跟踪:

    SimpleMessageListenerContainer] [SimpleAsyncTaskExecutor-11] [|] [|||] Consumer received fatal exception on startup 
org.springframework.amqp.rabbit.listener.exception.FatalListenerStartupException: Authentication failure
    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:476)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1280)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.amqp.AmqpAuthenticationException: com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using     authentication mechanism PLAIN. For details see the broker logfile.
    at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:65)
    at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:309)
    at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:547)
    at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils$1.createConnection(ConnectionFactoryUtils.java:90)
    at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.doGetTransactionalResourceHolder(ConnectionFactoryUtils.java:140)
    at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.getTransactionalResourceHolder(ConnectionFactoryUtils.java:76)
    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:472)
    ... 2 common frames omitted
Caused by: com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker     logfile.
    at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:339)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:813)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:767)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:887)
    at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:300)

 SimpleMessageListenerContainer] [SimpleAsyncTaskExecutor-11] [|] [|||] Stopping container from aborted consumer 
  [|] [|||] Waiting for workers to finish. 
  [|] [|||] Successfully waited for workers to finish.

即使出现致命异常(例如用户不存在时),也可以重试吗?

Any way to retry even on fatal exceptions like when the user does not exist?

推荐答案

默认情况下,身份验证失败被认为是致命的,不会重试.

Authentication failures are considered fatal by default and not retried.

您可以通过在侦听器容器 (possibleAuthenticationFailureFatal) 上设置一个属性来覆盖此行为.该属性不能用作引导属性,因此您必须覆盖引导的容器工厂...

You can override this behavior by setting a property on the listener container (possibleAuthenticationFailureFatal). The property is not available as a boot property so you have to override boot's container factory...

    @Bean(name = "rabbitListenerContainerFactory")
    public SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer, ConnectionFactory connectionFactory) {

        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        factory.setContainerConfigurer(smlc -> smlc.setPossibleAuthenticationFailureFatal(false));
        return factory;
    }

这篇关于RabbitHandler 在 Spring 中创建消费者并重试致命异常以用于侦听 RabbitMQ 的队列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆