2016-04-21 72 views
0

发送时使用队列100MB大小的消息,ActiveMQ的运行到内存不足的错误发送大文件时内存中,我们使用文件光标队列 -的ActiveMQ出去过队列

队列详细信息 - 我们的制片人正在发送每个消息大小为100MB的非持久性消息,生产者将通过同一个100MB消息的while循环继续生成。

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

我们有ActiveMQ的配置设置如下:

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

在消费方面,我们有一个异步的消费将继续监听进来的消息,并发送自动ACK。

这个程序之后运行了一段时间的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。

回答

2

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

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

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

+0

另一件事是我发送了大量1MB大小的非持久话题消息,但在制作人发送了大约7000份拷贝后,我得到了一个OOM。我有轮毂上的以下设置: \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t我不知道为什么producerFlowControl没有生效。 –