【问题标题】:Gracefully stop DefaultMessageListenerContainer having a receiveTimeout = -1优雅地停止具有 receiveTimeout = -1 的 DefaultMessageListenerContainer
【发布时间】:2013-01-21 08:15:14
【问题描述】:

有人可以指出一种在 Spring 中优雅地停止使用 receiveTimeout = -1 定义的 DefaultMessageListenerContainer 的方法(即,它正在使用 javax.jms.MessageConsumer#receive 的阻塞版本)吗?

实际上,我已经尝试了 DMLC 的 stop() 和 shutdown() 方法,但是消费者线程卡在了 receive() 调用上。

"heartBeatContainer-1" prio=6 tid=0x0304d800 nid=0x1d20 in Object.wait() [0x037ef000]
java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x22c48ab0> (a java.lang.Object)
    at java.lang.Object.wait(Object.java:485)
    at org.apache.activemq.SimplePriorityMessageDispatchChannel.dequeue(SimplePriorityMessageDispatchChannel.java:87)
    - locked <0x22c48ab0> (a java.lang.Object)
    at org.apache.activemq.ActiveMQMessageConsumer.dequeue(ActiveMQMessageConsumer.java:452)
    at org.apache.activemq.ActiveMQMessageConsumer.receive(ActiveMQMessageConsumer.java:504)
    at org.springframework.jms.connection.CachedMessageConsumer.receive(CachedMessageConsumer.java:70)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:430)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:310)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1069)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1061)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:958)
    at java.lang.Thread.run(Thread.java:662)

我无法关闭连接,因为还有其他侦听器应该继续使用消息。

【问题讨论】:

    标签: spring jms activemq spring-jms


    【解决方案1】:

    这就是receivetimeout 的重点——因此线程可以检查容器是否已关闭。将其设置为 -1 意味着线程将在 JMS 客户端中阻塞,直到出现消息。超时、检查容器状态和进行另一次接收没有太多开销。如果您不喜欢默认值,请将其设置为更高的数字(只要您在关闭容器时可以忍受延迟)。但是,将其设置为 -1 会导致您看到的行为。

    【讨论】:

    • 其实根据[docs.oracle.com/javaee/1.4/api/javax/jms/…如果消费者关闭了receive方法应该解除阻塞并返回null。人们会期望 DMLC 的 stop() 或 shutdown() 方法会关闭相关的消费者......
    • 停止容器不会关闭消费者。它只是设置一个布尔值,因此当侦听器线程返回其循环时,它可以自行关闭。
    猜你喜欢
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 2021-03-19
    • 2018-09-27
    • 2019-11-10
    • 1970-01-01
    • 2010-12-15
    • 2018-09-08
    相关资源
    最近更新 更多