我正在使用spring-boot和RabbitMQ开发一个项目。我在RabbitMQ上有两个队列,可以监听事件。
如果我启动该过程,它会运行几个小时,但之后会记录以下异常,并且所有消息都在RabbitMQ队列中,并且没有被处理。
com.rabbitmq.client.AlreadyClosedException: channel is already closed due to clean channel shutdown; protocol method: #method<channel.close>(reply-code=200, reply-text=OK, class-id=0, method-id=0)
at com.rabbitmq.client.impl.AMQChannel.ensureIsOpen(AMQChannel.java:198)
at com.rabbitmq.client.impl.AMQChannel.transmit(AMQChannel.java:312)
at com.rabbitmq.client.impl.AMQChannel.transmit(AMQChannel.java:306)
at com.rabbitmq.client.impl.ChannelN.basicAck(ChannelN.java:1165)
at sun.reflect.GeneratedMethodAccessor63.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:955)
at com.sun.proxy.$Proxy94.basicAck(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
com.rabbitmq.client.AlreadyClosedException: channel is already closed due to channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - unknown delivery tag 2930, class-id=60, method-id=80)
at com.rabbitmq.client.impl.AMQChannel.ensureIsOpen(AMQChannel.java:198)
at com.rabbitmq.client.impl.AMQChannel.transmit(AMQChannel.java:312)
at com.rabbitmq.client.impl.AMQChannel.transmit(AMQChannel.java:306)
at com.rabbitmq.client.impl.ChannelN.basicAck(ChannelN.java:1165)
at sun.reflect.GeneratedMethodAccessor63.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:955)
at com.sun.proxy.$Proxy94.basicAck(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
这些错误有时会发生在其中一个侦听器中,有时也会发生。一旦这些开始,队列处理就完全停止了。它们在多次重启服务器(Java)后开始工作
这是我的配置:
@Bean
public ConnectionFactory rabbitConnectionFactory() {
CachingConnectionFactory connectionFactory =
new CachingConnectionFactory(rabbitmqUrl);
connectionFactory.setUsername(rabbitmqUser);
connectionFactory.setPassword(rabbitmqPassword);
return connectionFactory;
}
@Bean
SimpleMessageListenerContainer containerQ1(ConnectionFactory connectionFactory,
@Qualifier("RabbitMQQ1IndexUpdateListenerAdapter") MessageListenerAdapter listenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(queue1);
container.setMessageListener(listenerAdapter);
container.setMaxConcurrentConsumers(2);
container.setMessageConverter(jackson2Converter());
container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
container.setPrefetchCount(30000);
return container;
}
@Bean
SimpleMessageListenerContainer containerQ2(ConnectionFactory connectionFactory,
@Qualifier("RabbitMQQ2IndexUpdateListenerAdapter") MessageListenerAdapter listenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(queue2);
container.setMessageListener(listenerAdapter);
container.setMaxConcurrentConsumers(2);
container.setMessageConverter(jackson2Converter());
container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
container.setPrefetchCount(30000);
return container;
}
@Bean(name = "RabbitMQQ1IndexUpdateListenerAdapter")
@Primary
MessageListenerAdapter Q1listenerAdapter(RabbitMQESIndexUpdateListener receiver) {
return new MessageListenerAdapter(receiver);
}
@Bean(name = "RabbitMQQ2IndexUpdateListenerAdapter")
MessageListenerAdapter Q2listenerAdapter(RabbitMQQ2IndexUpdateListener receiver) {
return new MessageListenerAdapter(receiver);
}
@Bean
public MessageConverter jackson2Converter() {
Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter();
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JodaModule());
converter.setJsonObjectMapper(mapper);
return converter;
}
请帮忙。