Camel ActiveMQ 客户端阻塞,临时存储使用率立即达到 100%
Posted
技术标签:
【中文标题】Camel ActiveMQ 客户端阻塞,临时存储使用率立即达到 100%【英文标题】:Camel ActiveMQ client blocking, temp storage usage immediately hits 100% 【发布时间】:2015-10-19 05:43:58 【问题描述】:我看到 activemq 的临时存储(配置为 100mb)的利用率为 100%,并且 activemq 客户端正在阻塞。这种 100% 的使用会永久保持,我不知道发生了什么
我有一条骆驼路线,它使用 JmsTransactionManager 从队列 (QUEUE.IN) 中消费。
public final class RouteUnderTest extends RouteBuilder
@Override
public void configure() throws Exception
from("activemq-transacted:QUEUE.IN")
.bean(myBean)
.to("activemq:QUEUE.OUT");
在处理来自该队列的消息时,我正在调用一个 spring-integration 客户端 (myBean),其配置如下
<int:gateway id="myBean" service-interface="MyBean">
<int:method name="request" request-channel="channel"/>
</int:gateway>
<int:chain input-channel="channel">
<int:transformer ref="transformedToJsonHere"/>
<jms:outbound-gateway request-destination-name="QUEUE.MYBEAN"
receive-timeout="5000"
explicit-qos-enabled="true"
time-to-live="5000"
delivery-persistent="false"/>
<int:transformer ref="transformedToAnObjectHere"/>
</int:chain>
我的代理配置为使用 LevelDB,并具有以下使用限制:
<persistenceAdapter>
<levelDB directory="$activemq.data/leveldb"/>
</persistenceAdapter>
<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage percentOfJvmHeap="70"/>
</memoryUsage>
<storeUsage>
<storeUsage limit="500 mb"/>
</storeUsage>
<tempUsage>
<tempUsage limit="100 mb"/>
</tempUsage>
</systemUsage>
</systemUsage>
当我的路由使用消息,然后尝试在 QUEUE.OUT 上放置非持久性消息时,客户端被阻止并且我的代理显示 100% 的临时存储使用率。
我看到了以下 activemq 日志
2015-07-28 15:44:59,678 | INFO | Usage(default:temp:queue://QUEUE.MYBEAN:temp) percentUsage=0%, usage=104857600, limit=104857600, percentUsageMinDelta=1%;Parent:Usage(default:temp) percentUsage=100%, usage=104857600, limit=104857600, percentUsageMinDelta=1%: Temp Store is Full (0% of 104857600). Stopping producer (ID:orbit-vm-55561-1438094698190-1:1:3:1) to prevent flooding queue://QUEUE.MYBEAN. See http://activemq.apache.org/producer-flow-control.html for more info (blocking for: 1s) | org.apache.activemq.broker.region.Queue | ActiveMQ NIO Worker 6
队列看起来像(您可以看到 QUEUE.IN 消息尚未出队,因为它仍在事务处理中,并且没有消息发送到 QUEUE.MYBEAN)
我可以使用以下任何一种方法来解决此问题:
-
使用 KahaDB 代替 LevelDB
增加临时存储限制(150MB 似乎可以,但我没有进行大量实验)
在 activemq.xml 中配置 tempDataStore(见下文)
配置 tempDataStore 时如下所示:
<tempDataStore>
<bean xmlns="http://www.springframework.org/schema/beans" class="org.apache.activemq.leveldb.LevelDBStore">
<property name="directory" value="$activemq.data/tmp" />
</bean>
</tempDataStore>
我应该补充一下,我们之前使用的是 KahaDB,并且效果很好,但是升级到 LevelDB 后就暴露了这个问题。恢复到 KahaDB 不是一种选择。
我希望有人能解释一下我们在这里看到的情况,因为结果真的很难理解。为什么使用 LevelDB 需要更高的临时使用限制?为什么显式配置 tempDataStore 也可以解决问题?
我不完全理解这里发生了什么,所以我担心只是稍微增加临时使用限制只会在以后隐藏问题。
版本:
ActiveMQ:5.11.1 骆驼:2.14.0 春季:4.0.8.RELEASE Spring 集成:4.0.5.RELEASE【问题讨论】:
【参考方案1】:我们在 ActiveMQ 5.13.2 中遇到了完全相同的问题
使用 LevelDB 时的解决方案是像您一样显式配置一个专用的tempDataStore
。
如果不是,代理对持久(持久使用)和非持久消息(临时使用)使用相同的存储 (LevelDB)。因此,您可能会在代理不再接受任何非持久消息的情况下结束,因为存储已经将持久消息保持在配置的tempUsage
限制。但是,如果您的 storeUsage
限制设置得更高,它将接受持久性...
使用 KahaDB 时,代理会自动使用另一个存储来存储非持久性消息(在 tmp 目录中创建)。所以你没有问题...
查看以下代码以获得更深入的信息:https://github.com/apache/activemq/blob/activemq-5.13.2/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java#L1739
阅读该代码时,请记住 LevelDBStore 实现了 PListStore
,但 KahaDBStore 没有...
【讨论】:
以上是关于Camel ActiveMQ 客户端阻塞,临时存储使用率立即达到 100%的主要内容,如果未能解决你的问题,请参考以下文章
Camel ActiveMQ + Spring boot 不读取 spring activemq 配置