[英]How to avoid shutdown of SimpleMessageListenerContainer in case of unexpected errors?
I am using Java boot 1.4.0 and 'spring-boot-starter-amqp' for connecting to rabbitMq. 我正在使用Java boot 1.4.0和'spring-boot-starter-amqp'连接到RabbitMq。 The message producer, consumer and the rabbitMq server are under my control.Things were working fine for a few months in production. 消息生产者,消费者和rabbitMq服务器都在我的控制之下。在生产中,几个月后一切正常。 But suddenly my consumer stopped with exceptions given below. 但是突然我的消费者停止了以下例外情况。 As I only produce messages which are always valid, I had no clue what went wrong. 因为我只生成始终有效的消息,所以我不知道出了什么问题。
But this caused my listener-container to shutdown. 但这导致我的监听器容器关闭。 And hence my message processing stopped.I had to manually restart my message-consumer program. 因此,我的消息处理停止了。我不得不手动重新启动我的消息消费程序。
So my questions are: 所以我的问题是:
Exception log: 异常日志:
2017-02-20 12:42:18.441 ERROR 18014 --- [writeToDBQQueueListenerContainer-17] osarlSimpleMessageListenerContainer : 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
One more exception: 还有一个例外:
2017-02-20 12:42:18.674 ERROR 18014 --- [imageQueueListenerContainer-53] osarlSimpleMessageListenerContainer : 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] osarlSimpleMessageListenerContainer : Stopping container from aborted consumer
My consumer sample code: 我的消费者示例代码:
@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 ...
}
I had the same problems a couple of months ago and this helped me. 几个月前,我遇到了同样的问题,这对我有所帮助。 If the version of your Rabbit Java Client is prior to 4.0.0 you don't have the recovery connection automatically, you need to set, like here: 如果Rabbit Java Client的版本低于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();
Try to check the documentation for RabbitMQ: Rabbit Client API 尝试查看RabbitMQ的文档: Rabbit Client API
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.