Activemq 在通过队列发送大文件时内存不足



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

队列详细信息 - 我们的生产者正在以每条消息 100MB 的大小发送非持久性消息,生产者将通过相同的 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 的消息)时,这似乎不会发生。

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

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

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

最新更新