0

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

知道它会这样做吗?下面是相关配置:

@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
4

2 回答 2

0

您没有显示“...卡在第 565 行周围的循环中...”的线程,但是如果按照您所说的进行操作,则线程可能卡在 activemq 中-默认receiveTimeout值为 1 秒(而您没有t 似乎改变了它)。

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

于 2017-04-26T13:00:03.957 回答
0

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

Gary Tully 添加了一条评论 - 24/Aug/15 10:19 使用客户端事务(即事务会话)并在有问题的目的地的代理上使用目的地策略条目 usePrefetchExtension=false。通过这种方式,您可以预取 1,并且在消费事务提交之前,只会发送一条消息。使用默认的 usePrefetchExtension=true,当第一条消息传递给消费者时,另一条消息会排队

于 2017-05-04T01:12:14.273 回答