当将ActiveMQ与大量持久性队列(250)á1000持久性TextMessagesá10 KB一起使用时,会出现问题。
一个场景需要这些消息在很长一段时间(几天)内保留在存储中,直到被消耗为止(为许多消费者分阶段分发大量数据以进行分发,这些数据可能会离线几天)。
在持久性存储中填充了这些消息之后,并且在代理重新启动之后,我们可以浏览/使用一些队列, 直到 30秒后调用#checkpoint。
此调用导致代理使用所有可用内存,而不会将其释放用于其他任务,例如队列浏览/使用。在内部,MessageCursor似乎决定内存不足,并停止将队列内容传送到浏览器/消费者。
=>有没有办法通过配置来避免这种行为,或者这是一个错误?
期望我们可以在任何情况下使用/浏览任何队列。
下面的设置已经投入生产了一段时间,并在ActiveMQ文档中应用了一些建议(目标策略,systemUsage,持久性存储选项等)。
除了上述设置之外,我们还对代理使用以下设置(顺便说一句:将memoryLimit更改为一个较小的值(如1mb)不会改变这种情况):
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry queue=">" producerFlowControl="false" optimizedDispatch="true" memoryLimit="128mb" timeBeforeDispatchStarts="1000">
<dispatchPolicy>
<strictOrderDispatchPolicy />
</dispatchPolicy>
<pendingQueuePolicy>
<storeCursor />
</pendingQueuePolicy>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
<systemUsage>
<systemUsage sendFailIfNoSpace="true">
<memoryUsage>
<memoryUsage limit="500 mb" />
</memoryUsage>
<storeUsage>
<storeUsage limit="80000 mb" />
</storeUsage>
<tempUsage>
<tempUsage limit="1000 mb" />
</tempUsage>
</systemUsage>
</systemUsage>
Run Code Online (Sandbox Code Playgroud)
如果我们根据memoryUsage和可用堆空间之间的差异将destinationPolicy中的cursorMemoryHighWaterMark设置为较高的值(例如150或600),则可以缓解这种情况,但这对生产系统而言并不是真正的选择。视图。
带有来自Oracle Mission Control的信息的Screenie,显示了从未从内存释放的ActiveMQTextMessage实例: