ActiveMQ記憶體設定和流控

五柳-先生發表於2015-07-07

啟動指令碼設定jvm的記憶體

if "%ACTIVEMQ_OPTS%" == "" set ACTIVEMQ_OPTS=-Xms1G-Xmx1G -Djava.util.logging.config.file=logging.properties

 

broker配置中的系統記憶體和磁碟空間使用量

         <systemUsage>

            <systemUsage>

                <memoryUsage>

                    <memoryUsagelimit="64 mb"/>

                </memoryUsage>

                <storeUsage>

                    <storeUsagelimit="100 gb"/>

                </storeUsage>

                <tempUsage>

                    <tempUsagelimit="50 gb"/>

                </tempUsage>

            </systemUsage>

        </systemUsage>

如果是嵌入式(embedded)方式使用的話,可以new一個SystemUsage來新增到BrokerService中去。這裡配置的memoryUsage一定要小於jvm中設定的數量。

5.9.0版本,如果設定的 memoryUsagelimit大於實際可用java heap size值,比如預設啟動 xmx=1G,那麼實際的java heap size大概是910M,

則broker啟動時會log.error提示設定記憶體出錯,然後強制使用實際java heap size* 70% = 637M作為memoryUsagelimit。


splitSystemUsageForProducersConsumers導致消費緩慢甚至無法消費的問題

其實broker中還可以單獨配置生產者使用的producerSystemUsage 和消費者使用的consumerSystemUsage,格式跟systeUsage一樣。

預設情況下,沒有配置producerSystemUsage 和 consumerSystemUsage,則生產者和消費者都使用systemUsage。

這時可能會因為生產者執行緒把記憶體用完,導致消費者執行緒處理緩慢甚至無法消費的問題。這種情況下,新增消費端的機器和消費者數量可能都無法增加消費的速度。

解決辦法就是:

在broker上設定splitSystemUsageForProducersConsumers=”true”,使得生產者執行緒和消費者執行緒各使用各的記憶體。

預設是 生產者執行緒記憶體:消費者執行緒記憶體 = 6:4。

也可以通過如下兩個引數設定生產者執行緒記憶體和消費者執行緒記憶體各一半:

producerSystemUsagePortion = 50

consumerSystemUsagePortion = 50

 

生產者流控

從5.x版本起,可以給每個producer單獨設定流控。流控簡單的說就是控制生產者的在記憶體使用限制下的行為。當然,流控的目的在於防止在將ActiveMQ作為記憶體MQ使用時,生產速度大於消費速度時將MQ撐爆的問題。

分兩個情況:

1、 同步傳送訊息(useAsynSend為false):此時將在SystemUsage的限制下,使用destinationPolicy中的policyEntry中的限制,例如:

<destinationPolicy>

  <policyMap>

    <policyEntries>

      <policyEntry queue="queueA"producerFlowControl="true"memoryLimit="1mb">   

  <pendingQueuePolicy>

    <vmQueueCursor/>

  </pendingQueuePolicy>

</policyEntry>

    </policyEntries>

  </policyMap>

</destinationPolicy>

限制非持久化時queueA 的記憶體使用量為1mb,達到這個記憶體使用量時直接阻塞掉producer,直到有空餘的記憶體時,才允許producer傳送訊息。

也可通過在systemUsage配置上設定sendFailIfNoSpace="true"或 sendFailIfNoSpaceAfterTimeout="3000"來控制客戶端異常和等待時間。

 

非同步傳送時,由於不阻塞生產者,

可以通過connctionFactory.setProducerWindowSize(1024000);

來控制broker確認收到訊息前生產者能傳送的最大資料量(位元組)。

 

 

消費者流控

消費者端,一般來說消費的越快越好,broker的積壓越小越好。

但是考慮到事務性和客戶端確認的情況,如果一個消費者一次獲取到了很多訊息卻都不確認,這會造成事務上下文變大,broker端這種“半消費狀態”的資料變多,所以ActiveMQ有一個prefetchSize引數來控制未確認情況下,最多可以預獲取多少條記錄。

預設情況如下:

持久化queue:1000條

非持久化queue: 1000條

持久化topic:100條

非持久化topic: 無限制

可以通過3中方式設定prefetchSize

1、  tcp://localhost:61616?jms.prefetchPolicy.all=50

2、  tcp://localhost:61616?jms.prefetchPolicy.queuePrefetch=1

3、  queue = new ActiveMQQueue("TEST.QUEUE?consumer.prefetchSize=10");

來自: http://blog.csdn.net/kimmking/article/details/9670653

相關文章