【问题标题】:Activemq went out of memory when sending large files over queue通过队列发送大文件时,Activemq 内存不足
【发布时间】:2016-08-15 04:18:42
【问题描述】:

当使用队列发送 100MB 大小的消息时,ActiveMQ 遇到内存不足错误,我们正在为队列使用文件游标 -

队列详细信息 - 我们的生产者正在以每条消息 100MB 的大小发送 NON-Persistent 消息,并且生产者将通过相同的 100MB 消息的 while 循环继续生产。

我们使用 activeMQ 附带的默认堆大小,最大为 1GB。

我们的 ActiveMQ 配置设置如下:

<policyEntry queue=">" producerFlowControl="false" memoryLimit="512mb" maxPageSize="1000000">               
<pendingQueuePolicy>                            
<fileQueueCursor /> 
</pendingQueuePolicy>
</policyEntry>  

在消费端,我们有一个异步消费者,它将继续监听传入的消息并发送自动确认。

这个程序运行一段时间后activeMQ抛出如下错误:

    2016-04-21 14:52:18,961 | ERROR | Error in thread 'ActiveMQ BrokerService.worker.1' | org.apache.activemq.broker.BrokerService | ActiveMQ BrokerService.worker.1
java.lang.OutOfMemoryError: Java heap space
    at org.apache.activemq.util.DataByteArrayOutputStream.ensureEnoughBuffer(DataByteArrayOutputStream.java:249)[activemq-client-5.13.1.jar:5.13.1]
    at org.apache.activemq.util.DataByteArrayOutputStream.writeBoolean(DataByteArrayOutputStream.java:140)[activemq-client-5.13.1.jar:5.13.1]
    at org.apache.activemq.openwire.v11.BaseDataStreamMarshaller.looseMarshalByteSequence(BaseDataStreamMarshaller.java:627)[activemq-client-5.13.1.jar:5.13.1]
    at org.apache.activemq.openwire.v11.MessageMarshaller.looseMarshal(MessageMarshaller.java:300)[activemq-client-5.13.1.jar:5.13.1]
    at org.apache.activemq.openwire.v11.ActiveMQMessageMarshaller.looseMarshal(ActiveMQMessageMarshaller.java:111)[activemq-client-5.13.1.jar:5.13.1]
    at org.apache.activemq.openwire.v11.ActiveMQTextMessageMarshaller.looseMarshal(ActiveMQTextMessageMarshaller.java:111)[activemq-client-5.13.1.jar:5.13.1]
    at org.apache.activemq.openwire.OpenWireFormat.marshal(OpenWireFormat.java:161)[activemq-client-5.13.1.jar:5.13.1]
    at org.apache.activemq.broker.region.cursors.FilePendingMessageCursor.getByteSequence(FilePendingMessageCursor.java:480)[activemq-broker-5.13.1.jar:5.13.1]
    at org.apache.activemq.broker.region.cursors.FilePendingMessageCursor.flushToDisk(FilePendingMessageCursor.java:440)[activemq-broker-5.13.1.jar:5.13.1]
    at org.apache.activemq.broker.region.cursors.FilePendingMessageCursor.onUsageChanged(FilePendingMessageCursor.java:401)[activemq-broker-5.13.1.jar:5.13.1]
    at org.apache.activemq.usage.Usage$1.run(Usage.java:308)[activemq-client-5.13.1.jar:5.13.1]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)[:1.8.0_74]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)[:1.8.0_74]
    at java.lang.Thread.run(Thread.java:745)[:1.8.0_74]

有谁知道如何解决这个问题?当我继续发送较小尺寸的消息时,这似乎不会发生,例如,小于 10MB 的消息。

【问题讨论】:

    标签: java apache jms activemq


    【解决方案1】:

    here 所述,非持久性消息将存储在内存中,而不是持久化到数据存储中。所以 1GB 会很快消失,特别是如果你不能像生产一样快地消耗。

    当然,您可以在 activemq.xml 中增加分配给 ActiveMQ 的内存量,但您最好还是坚持下去,即使您不需要恢复,并且可能会在一段时间后使消息过期以进行模拟非持久性(如有必要)。

    我会建议其他解决方案,例如将消息分解为更易于管理的内容,或者使用共享文件存储来存储数据并发送包含指向数据的指针的消息。除了 ActiveMQ 的处理开销之外,相信您对网络的影响会比正常情况大(例如,如果您与 AMQ 实例进行安全通信,那么您正在加密/解密 1 亿条消息,并不便宜)。

    【讨论】:

    • 另一件事是,我发送了许多大小为 1MB 的非持久主题消息,但在生产者发送了大约 7000 个副本后,我得到了 OOM。我在集线器上有以下设置: 我不知道为什么 producerFlowControl 是无效。
    猜你喜欢
    • 2018-12-23
    • 1970-01-01
    • 2018-04-07
    • 2019-05-30
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2012-03-15
    • 1970-01-01
    相关资源
    最近更新 更多