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

时间:2016-04-21 19:12:40

标签: java apache jms activemq

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

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

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

我们的ActiveMQ配置设置如下:

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

在消费方面,我们有一个Async消费者,它将继续收听消息并发送自动确认消息。

此程序运行一段时间后,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的消息。

1 个答案:

答案 0 :(得分:2)

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

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

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