Spring Integration JMS不会关闭

时间:2017-04-25 19:54:39

标签: java spring-boot spring-integration spring-jms spring-dsl

我有一个旨在使用来自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

2 个答案:

答案 0 :(得分:0)

你没有显示“......卡在第565行的循环中......”的线程,但是如果你正在按照你说的那样做,那么线程可能会卡在activemq中 - 默认receiveTimeout是1秒(你似乎没有改变它)。

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

答案 1 :(得分:0)

此问题与https://issues.apache.org/jira/browse/AMQ-5409重复。根据票:

  

Gary Tully添加了评论 - 24 / Aug / 15 10:19   使用客户端事务(因此是事务处理会话)并使用目标   在代理上的策略条目usePrefetchExtension = false   有问题的目的地。通过这种方式,您可以预取1,和   只有一条消息将被分派,直到消费交易   提交。使用默认的usePrefetchExtension = true,第一个时   消息被传递给消费者另一个排队等候