2016-04-21 69 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沒有生效。 –