ActiveMQ代理错误“;尝试恢复目标的JMS消息侦听器调用程序安装失败。原因:消费者已关闭;

ActiveMQ代理错误“;尝试恢复目标的JMS消息侦听器调用程序安装失败。原因:消费者已关闭;,activemq,spring-jms,Activemq,Spring Jms,我们已经在我们的环境中观察到,当消费者从ActiveMQ UI中被删除时。我们的流量非常低,并且观察到,最初我们有3个消费者,这些消费者在间隔几个小时后都被删除了,一旦我们重新启动消费者,它会再次刷新连接几个小时,我们在日志中没有看到任何错误,除了: Setup of JMS message listener invoker failed for destination 'queue-1' - trying to recover. Cause: The Consumer is closed 我

我们已经在我们的环境中观察到,当消费者从ActiveMQ UI中被删除时。我们的流量非常低,并且观察到,最初我们有3个消费者,这些消费者在间隔几个小时后都被删除了,一旦我们重新启动消费者,它会再次刷新连接几个小时,我们在日志中没有看到任何错误,除了:

Setup of JMS message listener invoker failed for destination 'queue-1' - trying to recover. Cause: The Consumer is closed
我使用AWS ActiveMQ代理,在代理日志中没有看到任何错误

我们使用
PoolConnectionFactory
ActiveMQConnectionFactory
按照建议为消费者创建连接池。我们正在使用ActiveMQ 5.15

@Bean
公共池连接工厂池连接工厂(){
ActiveMQConnectionFactory ActiveMQConnectionFactory=
新的ActiveMQConnectionFactory();
activeMQConnectionFactory.setBrokerURL(brokerUrl);
activeMQConnectionFactory.setUserName(用户名);
activeMQConnectionFactory.setPassword(密码);
activeMQConnectionFactory.setTrustAllPackages(true);
ActiveMQPrefetchPolicy ActiveMQPrefetchPolicy=新的ActiveMQPrefetchPolicy();
activeMQPrefetchPolicy.setQueuePrefetch(100);
//activeMQPrefetchPolicy.setQueuePrefetch();
activeMQConnectionFactory.setPrefetchPolicy(activeMQPrefetchPolicy);
PooledConnectionFactory PooledConnectionFactory=新的PooledConnectionFactory(activeMQConnectionFactory);
setMaxConnections(池大小);
返回池连接工厂;
}
@豆子
公共默认jmsListenerContainerFactory jmsListenerContainerFactory(){
DefaultJmsListenerContainerFactory工厂=
新的DefaultJmsListenerContainerFactory();
setConnectionFactory(pooledConnectionFactory());
setMessageConverter(jacksonJmsMessageConverter());
factory.setSessionAcknowledgeMode(会话.CLIENT_ACKNOWLEDGE);
factory.setConcurrency(“1-1”);
setErrorHandler(ActiveMQErrorHandler());
返回工厂;
}
@豆子
公共JmsTemplate JmsTemplate(){
JmsTemplate JmsTemplate=新的JmsTemplate(pooledConnectionFactory());
setMessageConverter(jacksonJmsMessageConverter());
返回jmsTemplate;
}
@豆子
公共队列(){
返回新的ActiveMQQueue(queueName);
}
@豆子
公共ErrorHandler ActiveMQErrorHandler(){
返回t->{
LOGGER.error(“JMS_LISTENER_error”);
};
}

给定提供的信息,听起来好像连接正在断开,客户端没有报告,或者远程设备正在关闭其端的使用者,池可能在执行某些用户操作之前不会注意到这一点

这是使用JMS池的其中一个问题,即池不能完全了解客户端的情况,因此检查池中的连接可能会导致获得一个过时的、不再活动的连接,因为IO中断不会出现在池层。解决此问题的一种方法是使用ActiveMQ客户端故障转移传输,以允许它在连接断开时自动重新连接到代理

您可以尝试的另一个选项是使用JMS连接池库,该库完成了一些额外的工作,以尝试更快地验证失败的连接和/或关闭的资源,并将其与创建使用故障转移的ActiveMQ连接的ConnectionFactory相匹配,以便像使用者这样的远程关闭的资源可以被捕获一些案例


最终,尽管您的代码仍需要处理JMS资源之外的潜在故障案例,并在需要时重试,如发送者看到安全异常等。池位并不能消除所有问题,在某些情况下,它们只是引入了您还没有想到的新的代理。

@JustinBertram我使用aws active mq代理,在代理中没有看到任何错误,在ActiveMQHandler中只记录日志,在日志中没有看到相同的打印。
@Bean public ErrorHandler ActiveMQErrorHandler(){return t->{LOGGER.error(“JMS_LISTENER_error”)}
即使有流量或没有流量,我们也需要让消费者连接,我们尝试了更高值的idletimeout,但也没有帮助是否可能有网络设备(如防火墙)正在关闭空闲连接?@JustinBertram我不这么认为,因为3个消费者在24小时后只运行了2个,1消费者在过去3天内仍在运行,即使没有流量,是否在活动mq消费者设置中缺少一个配置,以确保消费者始终连接到代理?您用于创建池连接的连接URI是什么?感谢共享此信息,由于消息侦听器长期运行,使用连接池外的连接没有多大好处,因此删除了侦听器MQ连接工厂的连接池映射,并让容器管理它,我们看不到消费者至少在过去24小时内没有停机。