RabbitHandler to create consumer and retry on Fatal Exception in Spring for queue on listening to rabbitmq

时光毁灭记忆、已成空白 提交于 2019-12-11 17:18:07

问题


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

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

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

Also Queue is defined like:-

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

I am using seperate code to initialise the Connection Factory.

My question is if rabbitmq is down for some time,it keeps on retrying to create a consumer but only if it recieves 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 rabbit mq without any consumers.

Stack Trace :-

    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 exception like user does not exist?


回答1:


Authentication failures are considered fatal by default and not retried.

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;
    }


来源:https://stackoverflow.com/questions/57912448/rabbithandler-to-create-consumer-and-retry-on-fatal-exception-in-spring-for-queu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!