【问题标题】:How to avoid blocking of queue browsing after ActiveMQ checkpoint callActiveMQ检查点调用后如何避免阻塞队列浏览
【发布时间】:2016-04-13 07:14:23
【问题描述】:

将 ActiveMQ 与大量持久性队列 (250) á 1000 个持久性 TextMessages á 10 KB 一起使用时会出现问题。

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

在 Persistence Store 被这些消息填充之后,并且在代理重新启动后,我们可以浏览/使用一些队列直到 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)。

除了上述设置之外,我们还为代理使用以下设置(顺便说一句:将 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>

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

带有来自 Oracle Mission Control 的信息的屏幕显示那些从未从内存中释放的 ActiveMQTextMessage 实例:

http://goo.gl/EjEixV

【问题讨论】:

  • 在我们的服务器意外关闭之后,我删除了“数据”文件夹中的所有内容并解决了错误。

标签: java memory activemq leveldb kahadb


【解决方案1】:

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

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

【讨论】:

  • 我尊重您的意见(我们有类似的方法来使用 dl-links 处理大量数据)。但即便如此,也会有一个取决于 msgs 数量的问题,导致对内存的强烈依赖,仅仅是因为 #checkpoint 或 #cleanup 的分页队列内容。恕我直言,在处理持久存储后必须进行更好的垃圾收集。主动生产者流控制不是一个选项,这实际上会导致组件之间的紧密耦合,我们希望有一个良好的松耦合,除了所需的持久存储(msgs 需要在代理重启后幸存)。
  • 根据用例,我们每秒为多达 1000 个消费者生成 1000-2000 条消息,通常所有消费者都会及时收到消息。在离线场景(例如网络问题)或消费者无法提交 tx 的情况下,持久存储就像一个魅力,并按预期存储消息(最多可以有 300 GB 的磁盘空间用于消息)。通常是没有问题的,因为消息消费非常快,但有时50-100个消费者会离线一段时间造成这个麻烦;因此“更多内存”只是#checkpoint 事情的临时解决方法。
【解决方案2】:

我们通过更改(队列)目的地来解决我们的问题 政策入口。

经过彻底调查(无需更改 ActiveMQ 源代码),结果是现在我们需要接受由用于#checkpoint/cleanup 进程和浏览/消费队列的单个 memoryLimit 参数定义的限制。

1.) 记忆

没有问题,如果我们使用更高的 memoryLimit(一起 具有更高的最大堆)以支持每个消息缓存 #checkpoint/cleanup 工作流程中的目的地和我们的要求 浏览/使用消息。

但是在我们的场景中更多的内存不是一个选项,我们需要处理 1024m max-heap 和 500m memoryLimit。

除此之外,应该详细讨论由于包含成百上千待处理消息的更持久队列以及某些离线/非活动消费者场景而不断设置更高的 memoryLimits (恕我直言)。

2.) 持久适配器

我们排除了持久性适配器作为问题的原因,因为如果我们切换不同类型的持久性存储(KahaDB、LevelDB、JDBC-PostgreSQL),行为不会改变。

在与 KahaDB 的调试会话期间,我们还看到定期检查点处理,存储按预期进行管理。

3.) 目的地政策/过期检查

如果我们禁用缓存和过期检查,我们的问题就完全消失了,这才是问题的真正原因。

记录了相应的属性,并且有一篇关于消息优先级的不错的博客文章,其描述非常适合我们的场景:

我们只是将 useCache="false" 和 expireMessagesPeriod="0" 添加到 政策入口:

<destinationPolicy>
    <policyMap>
        <policyEntries>
            <policyEntry queue=">" producerFlowControl="false" optimizedDispatch="true" memoryLimit="128mb" timeBeforeDispatchStarts="1000"
                                   useCache="false" expireMessagesPeriod="0">
                <dispatchPolicy>
                    <strictOrderDispatchPolicy />
                </dispatchPolicy>
                <pendingQueuePolicy>
                    <storeCursor />
                </pendingQueuePolicy>
            </policyEntry>
        </policyEntries>
    </policyMap>
</destinationPolicy>

如果我们不再使用内存缓存并且永远不会使用,后果很明显 检查消息是否过期。

因为我们既不使用消息过期也不使用消息优先级,并且当前的消息调度对我们来说足够快,考虑到给定的系统限制,这种权衡是可以接受的。

还应该考虑在特定工作流程中为内存消耗定义明确的预取限制。在我们的场景中,消息大小可以是 2 字节,最多约为 2 个字节。 100 KB,因此更多单独的策略条目和客户端消费者配置可能有助于优化与性能和内存使用有关的系统行为(请参阅http://activemq.apache.org/per-destination-policies.html)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 2016-02-15
    • 1970-01-01
    • 2014-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多