【发布时间】: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
【问题讨论】:
标签: apache-camel activemq spring-integration