我已经将ActiveMQ用作JMS实现(activemq-spring 5.12.1
)和Spring JMS集成(spring-jms 4.2.3.RELEASE
),所有这些都包含在Spring Boot Web应用程序中,部署在Tomcat上。
我遵循Spring配置(代码样本的详细程度减少了代码):
@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;
}
}
我的目标是配置两个使用者(因此concurrecny设置为2-2)并阻止任何消息缓存(因此预取策略设置为0)。
它有效,但会导致非常不愉快的副作用: 当我尝试通过Tomcat Manager取消部署应用程序时,它会暂停一段时间然后无限期地每秒产生以下DEBUG消息:
"DefaultMessageListenerContainer:563 - Still waiting for shutdown of 2 Message listener invokers"
。
因此,我每次都被迫杀死Tomcat进程。我做错了什么?
我的一个幸运镜头(ActiveMQ和Spring JMS的文档都没有用),是将预取策略设置为1而不是0.然后它优雅地取消部署,但我看不出它是如何关联的。
另外我很好奇,为什么要将缓存级别设置为CACHE_CONSUMER
,ActiveMQ需要创建两个使用者。当使用外部事务管理器时保留默认设置(CACHE_NONE
)时,只创建了一个使用者(而并发仍然设置为2 2-2,所以TaskExecutor
)。
如果重要,对于连接工厂和事务管理器,使用Atomikos
。我也可以粘贴它的配置,但似乎无关紧要。
答案 0 :(得分:0)
这很可能意味着消费者线程被“卡在”用户代码中;使用jstack进行线程转储以查看容器线程正在做什么。