ActiveMQ 引數優化

百聯達發表於2015-02-03

                          訊息遊標

如果消費者夠快的話,訊息會被及時消費,否則堵塞的訊息會被儲存(訊息遊標被pending

當佇列中的訊息被消費完時,阻塞的訊息被重新消費。

 

 

訊息遊標共有三類:Store based Cursor (預設的),VM Cursor(速度快,但對於非常慢的消費者或消費者長時間短看的情況不適用),File based CursorVM Cursor的升級版)

對於Topics來說,每一個subscriber,服務端都會維護一個queue 和一個 pending cursor.  因此對於持久和非持久訂閱要配置不同的策略

      

        

          

            

              

            

            

              

            

            

                

            

            

                

            

          

        

      

一些應用可能只是簡單的丟棄過期訊息,而不想將它們放到DLQ中,完全跳過了DLQ。在dead letter strategy死信策略上配置processExpired屬性為false,可以實現這個功能。 
 
   
     
       
       <!-- Set the following policy on all queues using the '>' wildcard --&gt  
         
         <!--  
           Tell the dead letter strategy not to process expired messages  
           so that they will just be discarded instead of being sent to  
           the DLQ  
         --&gt  
           
           processExpired="false" />  
           
         
       
     
   
...  
 

 

訊息頭
一個訊息物件分為三部分:訊息頭(Headers),屬性(Properties)和訊息體(Payload)。對於StreamMessage MapMessage,訊息本身就有特定的結構,而對於TextMessageObjectMessageBytesMessage是無結構的。一個訊息可以包含一些重要的資料或者僅僅是一個事件的通知。
訊息的Headers部分通常包含一些訊息的描述資訊,它們都是標準的描述資訊。包含下面一些值:
JMSDestination
訊息的目的地,Topic或者是Queue

JMSDeliveryMode
訊息的傳送模式:persistentnonpersistent。前者表示訊息在被消費之前,如果JMS提供者DOWN了,重新啟動後訊息仍然存在。後者在這種情況下表示訊息會被丟失。可以通過下面的方式設定:
Producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

JMSTimestamp
當呼叫send()方法的時候,JMSTimestamp會被自動設定為當前事件。可以通過下面方式得到這個值:
long timestamp = message.getJMSTimestamp();

JMSExpiration
表示一個訊息的有效期。只有在這個有效期內,訊息消費者才可以消費這個訊息。預設值為0,表示訊息永不過期。可以通過下面的方式設定:
producer.setTimeToLive(3600000); //
有效期1小時 1000毫秒 * 60 * 60分)

JMSPriority
訊息的優先順序。0-4為正常的優先順序,5-9為高優先順序。可以通過下面方式設定:
producer.setPriority(9);

JMSMessageID
一個字串用來唯一標示一個訊息,J主要是用來關聯多個Message,例如需要回復一個訊息的時候,通常把回覆的訊息的JMSCorrelationID設定為原來訊息的ID

JMSReplyTo
有時訊息生產者希望消費者回復一個訊息,JMSReplyTo為一個Destination,表示需要回復的目的地。當然消費者可以不理會它。

JMSCorrelationID
通常用來關聯多個Message。例如需要回復一個訊息,可以把JMSCorrelationID設定為所收到的訊息的JMSMessageID

JMSType
表示訊息體的結構,和JMS提供者有關。

JMSRedelivered
如果這個值為true,表示訊息是被重新傳送了。因為有時消費者沒有確認他已經收到訊息或者JMS提供者不確定消費者是否已經收到。

除了Header,訊息傳送者可以新增一些屬性(Properties)。這些屬性可以是應用自定義的屬性,JMS定義的屬性和JMS提供者定義的屬性。我們通常只適用自定義的屬性。

                                  記憶體設定

ACTIVEMQ_OPTS的配置〉=memoryUsage中配置〉=所有durable desitination設定之和

ACTIVEMQ_OPTS 設定為46GmemoryUsage 5G每一個producer的記憶體設定為32mb,設定的最大連線數為1000.       1000*32大約30G,遠遠大於5G memoryUsage,和46GACTIVEMQ_OPTS      建議適當調整producer的記憶體限制或連線數。

        

           

               

                   

               

               

                   

               

                

                   

               

           

       

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

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

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

解決辦法就是:

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

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

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

producerSystemUsagePortion = 50

consumerSystemUsagePortion = 50

                                        流控制

消費者流控

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

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

預設情況如下:

持久化queue1000

非持久化queue 1000

持久化topic100

非持久化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");

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28624388/viewspace-1424905/,如需轉載,請註明出處,否則將追究法律責任。

相關文章