Announcement Announcement Module
Collapse
No announcement yet.
Exception on startup if Rabbit AMQP broker is down Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Exception on startup if Rabbit AMQP broker is down

    Hi,

    I have a Queue bean (@Bean) defined in configuration (@Configuration) class like:
    Code:
    @Bean
    public Queue testQueue() {
    	return messagingAdmin().declareQueue();
    }
    If the Rabbit AMQP broker is down (i.e. service is down for some reason) I am getting java.net.ConnectException on application startup:

    Code:
    Caused by: org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused: connect
    	at org.springframework.amqp.rabbit.connection.RabbitUtils.convertRabbitAccessException(RabbitUtils.java:106)
    	at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:163)
    	at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:228)
    	at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils$1.createConnection(ConnectionFactoryUtils.java:77)
    	at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.doGetTransactionalResourceHolder(ConnectionFactoryUtils.java:121)
    	at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.getTransactionalResourceHolder(ConnectionFactoryUtils.java:67)
    	at org.springframework.amqp.rabbit.connection.RabbitAccessor.getTransactionalResourceHolder(RabbitAccessor.java:100)
    	at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:591)
    	at org.springframework.amqp.rabbit.core.RabbitAdmin.declareQueue(RabbitAdmin.java:129)
    What I want is to let Spring AMQP/RabbitMQ throw the exception in logs and let the application server continue to be run. How can I achieve this?

    Thanks

  • #2
    You don't need to explicitly declare the queue yourself - the 'messagingAdmin' bean will automatically declare the queue via a callback when the connection is successfully established. Just return an AnonymousQueue object from this @Bean; it will be slightly different to declareQueue() because spring-amqp will give the queue a unique name rather than the broker.

    Bear in mind that an @Bean definition is constructed once, during context initialization so, even if you trapped the exception there, there would be no way to declare the queue later.

    Hence the callback mechanism was created.

    Comment


    • #3
      Hi Gary,

      Thanks for the reply, can you please give an example? I tried this but not working:
      @Bean
      public Queue entityQueue() {
      //return new Queue("", false, true, true);
      return messagingAdmin().declareQueue();
      }

      I am getting below exception and Simple Message Listener Container is not able to startup:

      Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; reason: {#method<channel.close>(reply-code=404, r
      eply-text=NOT_FOUND - no queue '' in vhost 'mycompany-dev', class-id=50, method-id=10), null, "[B@e3404f"}


      We don't want to define explicit names to queues.

      Thanks

      Comment


      • #4
        Code:
        @Configuration
        public class ConfigTest {
        
        	public static void main(String[] args) throws Exception {
        		ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigTest.class);
        		RabbitTemplate template = ctx.getBean(RabbitTemplate.class);
        		Queue queue = ctx.getBean(Queue.class);
        		while (true) {
        			try {
        				template.convertAndSend(queue.getName(), "foo");
        			}
        			catch (Exception e) {
        				e.printStackTrace();
        			}
        			Thread.sleep(2000);
        		}
        	}
        
        	@Bean
        	public RabbitAdmin admin() {
        		return new RabbitAdmin(connectionFactory());
        	}
        
        	@Bean
        	public ConnectionFactory connectionFactory() {
        		CachingConnectionFactory cachingConnectionFactory = 
                            new CachingConnectionFactory(new com.rabbitmq.client.ConnectionFactory());
        		cachingConnectionFactory.setChannelCacheSize(2);
        		return cachingConnectionFactory;
        	}
        
        	@Bean
        	public Queue queue() {
        		return new AnonymousQueue();
        	}
        
        	@Bean
        	public RabbitTemplate template() {
        		RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory());
        		return rabbitTemplate;
        	}
        
        	@Bean
        	public SimpleMessageListenerContainer container() {
        		SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory());
        		container.setQueues(queue());
        		container.setMessageListener(new MessageListener() {
        
        			public void onMessage(Message message) {
        				System.out.println("received: " + message);
        			}
        		});
        		return container;
        	}
        }
        Last edited by Gary Russell; Aug 14th, 2012, 11:39 AM.

        Comment

        Working...
        X