TIMED_WAITING 在消息侦听器线程上

TIMED_WAITING on message listener thread

我使用 ActiveMQ Artemis 2.10.1 并遇到消息侦听器线程挂起问题。 线程将进入 TIMED_WAITING 并仅在客户端 JVM 重新启动后恢复。这是一个不确定的问题,不容易重现。客户端库版本为 2.16.0.

   java.lang.Thread.State: TIMED_WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at org.apache.activemq.artemis.core.client.impl.LargeMessageControllerImpl.waitCompletion(LargeMessageControllerImpl.java:301)
    - locked <0x000000050cd4e4f0> (a org.apache.activemq.artemis.core.client.impl.LargeMessageControllerImpl)
    at org.apache.activemq.artemis.core.client.impl.LargeMessageControllerImpl.saveBuffer(LargeMessageControllerImpl.java:275)
    - locked <0x000000050cd4e4f0> (a org.apache.activemq.artemis.core.client.impl.LargeMessageControllerImpl)
    at org.apache.activemq.artemis.core.client.impl.ClientLargeMessageImpl.checkBuffer(ClientLargeMessageImpl.java:159)
    at org.apache.activemq.artemis.core.client.impl.ClientLargeMessageImpl.getBodyBuffer(ClientLargeMessageImpl.java:91)
    at org.apache.activemq.artemis.jms.client.ActiveMQBytesMessage.readBytes(ActiveMQBytesMessage.java:220)
    at com.eu.jms.JMSEventBus.onMessage(JMSEventBus.java:385)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:746)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:684)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:651)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:317)
    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:748) ```

客户正在等待LargeMessageControllerImpl.waitCompletion。此等待将 not 永远阻塞。代码循环等待 large message 的数据包。只要大消息的数据包仍在到达,客户端就会继续等待,直到所有数据包都到达,或者如果数据包没有在给定的超时时间内到达,它将抛出错误。超时基于客户端 URL 上配置的 callTimeout。默认 callTimeout30000(即 30 秒)。

我的猜测是您的客户端收到了一条非常大的消息,或者网络速度变慢了,或者可能是这些情况的组合。如果您想更深入地了解正在发生的事情,您可以 turn on TRACE logging for org.apache.activemq.artemis.core.protocol.core.impl.RemotingConnectionImpl 查看到达客户端的单个大型消息包。

需要明确的是,线程转储显示您的客户端在这里等待并不奇怪,因为这是代码在接收大消息时最有可能等待的地方。这并不意味着客户端卡住了。

请记住,如果存在实际网络错误或连接丢失,客户端将抛出错误。此外,客户端维护一个独立的线程,该线程分别向代理发送和接收“ping”数据包。如果客户端没有得到预期的 ping 响应,那么它也会抛出一个错误。 none 您的客户端发生这种情况表明连接有效。

我建议检查队列头部消息的大小。代理支持任意大的消息,因此只要连接有效,客户端可能会很乐意坐下来接收许多演出。