java - ActiveMQ检查点调用后如何避免队列浏览阻塞

标签 java memory activemq leveldb kahadb

将 ActiveMQ 与大量持久队列 (250) á 1000 条持久文本消息 á 10 KB 结合使用时出现问题。

某个场景要求这些消息在存储中保留很长一段时间(几天),直到它们被消耗(大量数据被分阶段分发给许多消费者,这些数据可能会离线几天)。

在持久性存储充满这些消息后,并且在代理重新启动后,我们可以浏览/使用一些队列,直到 30 秒后调用 #checkpoint。

此调用会导致代理使用所有可用内存,并且不会将其释放以用于其他任务,例如队列浏览/使用。在内部,MessageCursor 似乎决定没有足够的内存并停止向浏览器/消费者传递队列内容。

=> 有没有办法通过配置来避免这种行为,或者这是一个错误?

期望我们可以在任何情况下使用/浏览任何队列。

下面的设置已经投入生产一段时间了,并且应用了 ActiveMQ 文档中的一些建议(目标策略、systemUsage、持久性存储选项等)

  • 行为已使用 ActiveMQ 进行测试:5.11.2、5.13.0 和 5.5.1。
  • 内存设置:Xmx=1024m
  • Java:1.8 或 1.7
  • 操作系统:Windows、MacOS、Linux
  • PersistenceAdapter:KahaDB 或 LevelDB
  • 光盘:足够的可用空间 (200 GB) 和物理内存(最大 16 GB)。

除了上述设置之外,我们还对代理使用以下设置(顺便说一句:将内存限制更改为较低的值(例如 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>

如果我们将destinationPolicy中的cursorMemoryHighWaterMark设置为更高的值,例如150600,具体取决于内存使用情况和可用堆之间的差异space 可以稍微缓解一下这种情况,但在我看来,这对于生产系统来说并不是一个真正的选择。

包含来自 Oracle Mission Control 的信息的 Screenie,显示那些从未从内存中释放的 ActiveMQTextMessage 实例:

http://goo.gl/EjEixV

最佳答案

我遇到了类似的问题,ActiveMQ 并不是真正设计为“数据库”;消息必须通过 ActiveMQ 流动,对于这些长期存储,我建议使用数据库或使用 FTP 交换文件。

我还建议使用 ProducerFlowControl="true",这样如果 ActiveMQ 无法处理消息,它会减慢生产者的速度。

关于java - ActiveMQ检查点调用后如何避免队列浏览阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34679854/

相关文章:

java - Seam Framework 中的非法状态异常

java - 编写提醒应用程序无法创建新对象

java - 汤姆EE : JMS Provider - ActiveMQ with AMQP Wire protocol

java - InputStream 的自定义实现

java - Java中的半精度 float

Javascript:将类/对象引用设置为 NULL,内存中的子对象/类会发生什么?

java - 在运行时更改堆栈大小

c# - 为什么拆箱比装箱快 100 倍

java - 如何配置 ActiveMQ 以将 'anonymous' 用户和角色分配给未经身份验证的用户

java - 如何暂停和恢复 JMS 消息的异步消费