Java Spring集成JMS不会关闭

Java Spring集成JMS不会关闭,java,spring-boot,spring-integration,spring-jms,spring-dsl,Java,Spring Boot,Spring Integration,Spring Jms,Spring Dsl,我有一个服务,用于使用来自JMS队列的消息。这段代码似乎永远不会在关机时退出,并被困在org.springframework.jms.listener.DefaultMessageListenerContainer第565行的循环中 你知道它会这么做吗?以下是相关配置: @Bean @Primary public ConnectionFactory myConnectionFactory() { ActiveMQConnectionFactory connecti

我有一个服务,用于使用来自JMS队列的消息。这段代码似乎永远不会在关机时退出,并被困在
org.springframework.jms.listener.DefaultMessageListenerContainer
第565行的循环中

你知道它会这么做吗?以下是相关配置:

@Bean
    @Primary
    public ConnectionFactory myConnectionFactory() {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
        ActiveMQPrefetchPolicy activeMQPrefetchPolicy = new ActiveMQPrefetchPolicy();
        activeMQPrefetchPolicy.setQueuePrefetch(0);  // 1 message per connection, no prefetch
        connectionFactory.setPrefetchPolicy(activeMQPrefetchPolicy);
        connectionFactory.setBrokerURL("tcp://" + jmsSettings.getHost() + ":" + jmsSettings.getPort());
        return connectionFactory;
    }

@Bean 
    public JmsMessageDrivenChannelAdapter messageSource() {
        DefaultMessageListenerContainer defaultMessageListenerContainer = Jms.container(myConnectionFactory(), "incoming.queue")
                .maxConcurrentConsumers(jmsSettings.getMaxConcurrentConnections())
                .get();
        return Jms.messageDrivenChannelAdapter(defaultMessageListenerContainer)
            .get();
    }
线程转储产生大量信息。我相信这是相关的部分

"DefaultMessageListenerContainer-1": awaiting notification on [1f9c4a73]
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at org.apache.activemq.SimplePriorityMessageDispatchChannel.dequeue(SimplePriorityMessageDispatchChannel.java:87)
at org.apache.activemq.ActiveMQMessageConsumer.dequeue(ActiveMQMessageConsumer.java:452)
at org.apache.activemq.ActiveMQMessageConsumer.receive(ActiveMQMessageConsumer.java:575)
at org.springframework.jms.support.destination.JmsDestinationAccessor.receiveFromConsumer(JmsDestinationAccessor.java:130)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:416)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:302)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:255)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1166)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1158)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1055)
at java.lang.Thread.run(Thread.java:745)
问题似乎在这个代码块中。activeInvokerCount永远不会变为0,因此它卡在循环中。
org.springframework.jms.listener.DefaultMessageListenerContainer

// Waiting for AsyncMessageListenerInvokers to deactivate themselves...
            while (this.activeInvokerCount > 0) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Still waiting for shutdown of " + this.activeInvokerCount +
                            " message listener invokers");
                }
                long timeout = getReceiveTimeout();
                if (timeout > 0) {
                    this.lifecycleMonitor.wait(timeout);
                }
                else {
                    this.lifecycleMonitor.wait();
                }
            }
启用跟踪日志记录在尝试关闭时显示此信息。一遍又一遍

2017-04-26 13:23:49.127 TRACE 8752 --- [WriteCheckTimer] o.a.a.t.AbstractInactivityMonitor        : tcp://localhost/127.0.0.1:61616@49451 no message sent since last write check, sending a KeepAliveInfo
2017-04-26 13:23:49.127 DEBUG 8752 --- [yMonitor Worker] o.a.a.t.AbstractInactivityMonitor        : Running WriteCheck[tcp://127.0.0.1:61616]
2017-04-26 13:23:50.511 DEBUG 8752 --- [n(12)-127.0.0.1] o.s.j.l.DefaultMessageListenerContainer  : Still waiting for shutdown of 1 message listener invokers
2017-04-26 13:23:51.512 DEBUG 8752 --- [n(12)-127.0.0.1] o.s.j.l.DefaultMessageListenerContainer  : Still waiting for shutdown of 1 message listener invokers
2017-04-26 13:23:52.512 DEBUG 8752 --- [n(12)-127.0.0.1] o.s.j.l.DefaultMessageListenerContainer  : Still waiting for shutdown of 1 message listener invokers
2017-04-26 13:23:53.512 DEBUG 8752 --- [n(12)-127.0.0.1] o.s.j.l.DefaultMessageListenerContainer  : Still waiting for shutdown of 1 message listener invokers
2017-04-26 13:23:54.512 DEBUG 8752 --- [n(12)-127.0.0.1] o.s.j.l.DefaultMessageListenerContainer  : Still waiting for shutdown of 1 message listener invokers
2017-04-26 13:23:55.512 DEBUG 8752 --- [n(12)-127.0.0.1] o.s.j.l.DefaultMessageListenerContainer  : Still waiting for shutdown of 1 message listener invokers
2017-04-26 13:23:56.512 DEBUG 8752 --- [n(12)-127.0.0.1] o.s.j.l.DefaultMessageListenerContainer  : Still waiting for shutdown of 1 message listener invokers
2017-04-26 13:23:57.512 DEBUG 8752 --- [n(12)-127.0.0.1] o.s.j.l.DefaultMessageListenerContainer  : Still waiting for shutdown of 1 message listener invokers
2017-04-26 13:23:58.512 DEBUG 8752 --- [n(12)-127.0.0.1] o.s.j.l.DefaultMessageListenerContainer  : Still waiting for shutdown of 1 message listener invokers
2017-04-26 13:23:59.127 DEBUG 8752 --- [WriteCheckTimer] o.a.a.t.AbstractInactivityMonitor        : WriteChecker 10000 ms elapsed since last write check.
2017-04-26 13:23:59.127 TRACE 8752 --- [WriteCheckTimer] o.a.a.t.AbstractInactivityMonitor        : tcp://localhost/127.0.0.1:61616@49451 no message sent since last write check, sending a KeepAliveInfo
2017-04-26 13:23:59.127 DEBUG 8752 --- [yMonitor Worker] o.a.a.t.AbstractInactivityMonitor        : Running WriteCheck[tcp://127.0.0.1:61616]
2017-04-26 13:23:59.512 DEBUG 8752 --- [n(12)-127.0.0.1] o.s.j.l.DefaultMessageListenerContainer  : Still waiting for shutdown of 1 message listener invokers
2017-04-26 13:24:00.512 DEBUG 8752 --- [n(12)-127.0.0.1] o.s.j.l.DefaultMessageListenerContainer  : Still waiting for shutdown of 1 message listener invokers
2017-04-26 13:24:01.512 DEBUG 8752 --- [n(12)-127.0.0.1] o.s.j.l.DefaultMessageListenerContainer  : Still waiting for shutdown of 1 message listener invokers
2017-04-26 13:24:02.512 DEBUG 8752 --- [n(12)-127.0.0.1] o.s.j.l.DefaultMessageListenerContainer  : Still waiting for shutdown of 1 message listener invokers
2017-04-26 13:24:03.512 DEBUG 8752 --- [n(12)-127.0.0.1] o.s.j.l.DefaultMessageListenerContainer  : Still waiting for shutdown of 1 message listener invokers
2017-04-26 13:24:04.512 DEBUG 8752 --- [n(12)-127.0.0.1] o.s.j.l.DefaultMessageListenerContainer  : Still waiting for shutdown of 1 message listener invokers

您不会显示“…卡在第565行周围的循环中…”的线程,但如果它按照您所说的那样执行,则该线程可能卡在activemq中-默认的
receiveTimeout
为1秒(并且您似乎没有更改它)


如果打开跟踪日志记录,则每次我们尝试接收消息时都会收到一条日志消息,并且在没有收到消息的情况下超时。如果您在此状态下未看到此类消息,则表明ActiveMQ存在问题。

此问题与。根据车票:

Gary Tully添加了一条评论-2015年8月24日10:19 使用客户端事务(即事务会话)并使用目的地 代理上的策略条目usePrefetchExtension=false 目的地有问题。这样,预回迁可以为1,并且 只有一条消息将被发送到消费事务 承诺。当第一个 消息被传递给消费者,另一个被排队


进行线程转储以查看调用程序线程正在做什么。相关的块在上面。转储中显然有更多内容,但似乎并不相关。事实证明,这与我的连接工厂上的自定义预取策略有关。一旦我把它去掉,一切正常@GaryRussell知道为什么预回迁策略不好吗?仅供参考,此配置的目的是允许多线程消费消息,如果其中一条消息恰好需要更长的时间才能“消费”(即具有某些业务逻辑的流程),则不会有任何消费者阻塞。有没有更好的方法来配置DSL?对不起,不知道预取;您可以简单地增加并发性(
concurrency
,或
concurrentcummers
maxconcurrentcummers
),容器将根据需要向上/向下调整并发性(但不要使用具有可变并发性的缓存连接工厂-请参阅DMLC javadocs)(来自Spring类)。我相信是我发布的工作线程没有关闭,这似乎导致了无限循环。为什么会这样?我理解这一点,但我需要堆栈跟踪来确认关闭是通过侦听器适配器
destroy()调用的
。正如我所说,调用程序线程当前在activemq中,在退出接收之前不会对关闭做出响应。如果没有(并且您没有看到我提到的跟踪日志),应该在一秒钟内发生那么问题出在activemq中。您使用的是什么版本?我刚刚更新到最新的activemq API--5.7.0。我仍然看到问题。我将发布一个完整的线程转储。嗯,线程转储太大,无法发布。我将尝试对其进行微调,以使其低于字符限制。是否有我应该查找的特定线程?您启用了吗如我所建议的跟踪日志记录?您可以将大型转储发布到github gist或pastebin之类的地方。