Java 由于特定的SpringJMS配置,无法从Tomcat取消部署
我使用ActiveMQ作为JMS实现(Java 由于特定的SpringJMS配置,无法从Tomcat取消部署,java,spring,tomcat,activemq,spring-jms,Java,Spring,Tomcat,Activemq,Spring Jms,我使用ActiveMQ作为JMS实现(ActiveMQSpring5.12.1)和SpringJMS集成(SpringJMS 4.2.3.RELEASE),所有这些都包装在SpringBootWeb应用程序中,部署在Tomcat上 我有以下Spring配置(代码因代码示例的冗长而减少): 我的目标是配置两个使用者(因此concurrecny设置为2-2)并防止任何消息缓存(因此预取策略设置为0) 它有效,但会产生非常不愉快的副作用: 当我试图通过Tomcat Manager取消部署应用程序时,它
ActiveMQSpring5.12.1
)和SpringJMS集成(SpringJMS 4.2.3.RELEASE
),所有这些都包装在SpringBootWeb应用程序中,部署在Tomcat上
我有以下Spring配置(代码因代码示例的冗长而减少):
我的目标是配置两个使用者(因此concurrecny设置为2-2)并防止任何消息缓存(因此预取策略设置为0)
它有效,但会产生非常不愉快的副作用:
当我试图通过Tomcat Manager取消部署应用程序时,它会挂起一段时间,然后无限期地挂起,每秒钟产生以下调试消息:
“DefaultMessageListenerContainer:563-仍在等待关闭2个消息侦听器调用程序”
因此,每次我都被迫杀死Tomcat进程。我做错了什么
我的幸运之举之一(ActiveMQ和SpringJMS的文档都没有那么大帮助)是将预回迁策略设置为1而不是0。然后它优雅地展开,但我看不出它是如何关联的
我也很好奇,为什么ActiveMQ需要将缓存级别设置为cache\u CONSUMER
,才能创建两个使用者。当保留默认设置时(CACHE\u NONE
在使用外部事务管理器时),只创建了一个使用者(而并发仍然设置为两个2-2,TaskExecutor
)
如果重要的话,对于连接工厂和事务管理器,将使用
Atomikos
。我也可以粘贴它的配置,但它似乎无关紧要。这很可能意味着消费者线程“卡在”用户代码中;使用jstack进行线程转储,查看容器线程正在做什么
@Configuration
@EnableJms
public class AppConfiguration {
@Bean
public XAConnectionFactory jmsXaConnection(String activeMqUsername, String activeMqPassword) {
ActiveMQXAConnectionFactory activeMQXAConnectionFactory = new ActiveMQXAConnectionFactory(activeMqUsername, activeMqPassword, activeMqUrl);
ActiveMQPrefetchPolicy prefetchPolicy = new ActiveMQPrefetchPolicy();
prefetchPolicy.setAll(0);
activeMQXAConnectionFactory.setPrefetchPolicy(prefetchPolicy);
return activeMQXAConnectionFactory;
}
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory connectionFactory, JtaTransactionManager jtaTransactionManager) {
DefaultJmsListenerContainerFactory containerFactory = new DefaultJmsListenerContainerFactory();
containerFactory.setConnectionFactory(connectionFactory);
containerFactory.setTransactionManager(jtaTransactionManager);
containerFactory.setSessionTransacted(true);
containerFactory.setTaskExecutor(Executors.newFixedThreadPool(2));
containerFactory.setConcurrency("2-2");
containerFactory.setCacheLevel(DefaultMessageListenerContainer.CACHE_CONSUMER);
return containerFactory;
}
}