2017-02-28 332 views
1

我正在使用Java boot 1.4.0和'spring-boot-starter-amqp'來連接到rabbitMq。消息製作者,消費者和rabbitMq服務器都在我的控制之下。在製作過程中,幾個月的事情都很好。但突然我的消費者停止了下面給出的例外。由於我只生產總是有效的信息,我不知道哪裏出了問題。如何避免在發生意外錯誤時關閉SimpleMessageListenerContainer?

但是這導致我的聽者容器關閉。因此我的消息處理已停止。我不得不手動重新啓動消息使用者程序。

所以我的問題是:

  1. 我們能否避免偵聽器容器完全關閉任何意外情況?
  2. 是否有可能優雅地丟棄這樣的消息並保持偵聽器容器活着?
  3. 如果沒有,那麼我是否可以通過這些方法檢查我的所有偵聽器容器是否正在運行,如果我發現它們已經死了就啓動它們? (注:我看着RabbitListenerEndpointRegistry.getListenerContainers(),但看起來它不包括SimpleMessageListenerContainer一樣的容器。)

異常日誌:

2017-02-20 12:42:18.441 ERROR 18014 --- [writeToDBQQueueListenerContainer-17] o.s.a.r.l.SimpleMessageListenerContainer : Consumer thread error, thread abort. 
 
java.lang.NoClassDefFoundError: org/springframework/messaging/handler/annotation/support/MethodArgumentNotValidException 
 
    at org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler$DefaultExceptionStrategy.causeIsFatal(ConditionalRejectingErrorHandler.java:110) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na] 
 
    at org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler$DefaultExceptionStrategy.isFatal(ConditionalRejectingErrorHandler.java:97) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na] 
 
    at org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler.handleError(ConditionalRejectingErrorHandler.java:72) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na] 
 
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeErrorHandler(AbstractMessageListenerContainer.java:625) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na] 
 
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.handleListenerException(AbstractMessageListenerContainer.java:852) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na] 
 
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:685) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na] 
 
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1165) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na] 
 
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:1149) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na] 
 
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1100(SimpleMessageListenerContainer.java:95) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na] 
 
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1312) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na] 
 
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_91] 
 
Caused by: java.lang.ClassNotFoundException: org.springframework.messaging.handler.annotation.support.MethodArgumentNotValidException 
 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_91] 
 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_91] 
 
    at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:89) ~[KattaQueueManager-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] 
 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_91] 
 
    ... 11 common frames omitted

還有一例外:

2017-02-20 12:42:18.674 ERROR 18014 --- [imageQueueListenerContainer-53] o.s.a.r.l.SimpleMessageListenerContainer : Consumer thread error, thread abort. 
 

 
java.lang.NoClassDefFoundError: com/rabbitmq/utility/Utility 
 
     at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.checkShutdown(BlockingQueueConsumer.java:348) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na] 
 
     at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.nextMessage(BlockingQueueConsumer.java:402) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na] 
 
     at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1160) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na] 
 
     at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:1149) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na] 
 
     at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1100(SimpleMessageListenerContainer.java:95) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na] 
 
     at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1312) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na] 
 
     at java.lang.Thread.run(Thread.java:745) [na:1.8.0_91] 
 
Caused by: java.lang.ClassNotFoundException: com.rabbitmq.utility.Utility 
 
     at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_91] 
 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_91] 
 
     at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:89) ~[KattaQueueManager-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] 
 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_91] 
 
     ... 7 common frames omitted 
 

 
2017-02-20 12:42:18.675 ERROR 18014 --- [imageQueueListenerContainer-53] o.s.a.r.l.SimpleMessageListenerContainer : Stopping container from aborted consumer

我的消費者的示例代碼:

@Bean 
public MessageConverter jsonMessageConverter(){ 
    //return new JsonMessageConverter(); 
    Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter(); 

    converter.setClassMapper(new ClassMapper() { 
     @Override 
     public Class<?> toClass(MessageProperties properties) { 
      return String.class; 
     } 

     @Override 
     public void fromClass(Class<?> clazz, MessageProperties properties) { 
     } 
    }); 

    return converter; 
} 

@Bean 
public ConnectionFactory connectionFactory() 
{ 
    CachingConnectionFactory connectionFactory = 
      new CachingConnectionFactory(_rabbitmqHost, _rabbitmqPort); 
    return connectionFactory; 
} 

@Bean 
public RabbitTemplate rabbitTemplate() 
{ 
    RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory()); 
    rabbitTemplate.setMessageConverter(jsonMessageConverter()); 
    return rabbitTemplate; 
} 

@Bean 
TopicExchange exchange() 
{ 
    return new TopicExchange("MyExchange"); 
} 

@Bean 
public Queue mainQueue() 
{ 
    return new Queue("MyMainQ"); 
} 

@Bean 
public Binding mainRouteBinding() 
{ 
    return BindingBuilder.bind(mainQueue()).to(exchange()).with("MyMainQ"); 
} 

@Bean 
SimpleMessageListenerContainer mainQueueListenerContainer(
     ConnectionFactory connectionFactory, 
     @Qualifier("mainQueueListenerAdapter") MessageListenerAdapter listenerAdapter) 
{ 
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(); 
    container.setConnectionFactory(connectionFactory); 
    container.setQueues(mainQueue()); 

    container.setMessageConverter(jsonMessageConverter()); 

    container.setMessageListener(listenerAdapter); 
    container.setConcurrentConsumers(1); 
    return container; 
} 

@Bean 
MessageListenerAdapter mainQueueListenerAdapter(MainConsumer receiver) 
{ 
    MessageListenerAdapter msgAdapter = new MessageListenerAdapter(receiver, "receiveMessage"); 

    msgAdapter.setMessageConverter(jsonMessageConverter()); 

    return msgAdapter; 
} 

@Bean 
MainConsumer getMainConsumer() 
{ 
    return new MainConsumer(); 
} 

// 
//The receiving method in MainConsumer class looks as given below 
public void receiveMessage(String message) 
{ 
    // My business logic goes here ... 
} 
+0

從堆棧跟蹤看來,類路徑中缺少少量類/ jar,檢查它們是否存在/包含在類路徑中 –

+0

感謝評論Bond。它是一個完整的工作設置,運行幾個月。絕對需要所有必需的組件/罐子。 –

+0

okies ..你在日誌中看到任何'ExceptionInInitializerError'嗎? –

回答

0

幾個月前我有同樣的問題,這幫助了我。 如果你的兔子Java客戶端的版本早於4.0.0你不具備自動恢復連接,你需要設置,喜歡這裏:

ConnectionFactory factory = new ConnectionFactory(); 
factory.setUsername(userName); 
factory.setPassword(password); 
factory.setVirtualHost(virtualHost); 
factory.setHost(hostName); 
factory.setPort(portNumber); 

// connection that will recover automatically 
factory.setAutomaticRecoveryEnabled(true); 

// attempt recovery every 10 seconds 
factory.setNetworkRecoveryInterval(10000); 

Connection conn = factory.newConnection(); 

嘗試檢查文檔的RabbitMQ: Rabbit Client API

+0

謝謝@兄弟。我正在使用Spring Boot 1.4.0發行版中的'spring-boot-starter-amqp'。據我瞭解,默認情況下,它具有主要的重新連接功能,可以處理基本連接丟失。所以在這方面大多沒什麼可配置的。 –

相關問題