activeMQ深入瞭解—隊列模式手動控制消費

相信經過了解,基本使用activemq後,大家一定知道隊列裏面有ACK模式,他的類型有以下幾種

1、AUTO_ACKNOWLEDGE = 1    自動確認

2、CLIENT_ACKNOWLEDGE = 2    客戶端手動確認

3、DUPS_OK_ACKNOWLEDGE = 3    自動批量確認

4、SESSION_TRANSACTED = 0    事務提交併確認

5、INDIVIDUAL_ACKNOWLEDGE = 4    單條消息確認(自定義ACK_MODE)


使用方式一般有

1、使用連接創建session

               Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);   

2、spring中配置

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
       
             <property name="connectionFactory" ref="connectionFactory"></property>
       
             <property name="defaultDestination" ref="destination"></property>
       
             <property name="messageConverter" ref="jmsMessageConverter"></property>
       
             <property name="sessionAcknowledgeMode" value="2" />
   
           </bean>

 注意:當我們只配置了這些,以爲在消費者出獲取消息調用message.acknowledge();方法就能控制消息的消費,很明顯,不行!

       查閱資料你會發現,當你獲取消息的時候,默認的獲取方法裏面沒有走你的這些配置直接就消費了消息,所以就達不到我們想要的效果,手動控制消費。所以,我們需要重寫一個方法手動獲取,但是帶上自己的參數。

[html] view plain copy
  1. /**  
  2.      * 接收消息   
  3.      * @param session   
  4.      * @param consumer   
  5.      * @param autoAcknowledge 是否開啓手動消費  
  6.      * @return   
  7.      * @throws JMSException   
  8.      */  
  9.     protected Message doReceive(Session session, MessageConsumer consumer,Boolean autoAcknowledge) throws JMSException {    
  10.         try {    
  11.             this.consumer = consumer;    
  12.             //Use transaction timeout (if available).    
  13.             long timeout = 1000;  
  14.             Message message = doReceive(consumer, timeout);    
  15.             if (session.getTransacted()) {    
  16.                 // Commit necessary - but avoid commit call within a JTA transaction.    
  17.                 // 如果開啓了jta事物,那麼不會進行提交,jta事物會直接覆蓋掉session事物    
  18.                 if (isSessionLocallyTransacted(session)) {    
  19.                     // Transacted session created by this template -> commit.    
  20.                     //創建事物回話  
  21.                     JmsUtils.commitIfNecessary(session);    
  22.                 }    
  23.             }    
  24.             //autoAcknowledge如果爲真,不進行自動確認    
  25.             else if (isClientAcknowledge(session) && !autoAcknowledge) {    
  26.                 // Manually acknowledge message, if any.    
  27.                 if (message != null) {    
  28.                     message.acknowledge();    
  29.                 }    
  30.             }    
  31.             return message;    
  32.         }    
  33.         finally {    
  34.             consumer = null;    
  35.         }    
  36.     }  

[html] view plain copy
  1. /**   
  2.      * 由於上面的doReceive(Session session, MessageConsumer consumer,Boolean autoAcknowledge)需要調用這個方法,   
  3.      * 而在父類裏面這個方法是私有的,所以直接拷貝下來了   
  4.      * @param consumer   
  5.      * @param timeout   
  6.      * @return   
  7.      * @throws JMSException   
  8.      */  
  9.     private Message doReceive(MessageConsumer consumer, long timeout) throws JMSException {    
  10.         if (timeout == RECEIVE_TIMEOUT_NO_WAIT) {    
  11.             return consumer.receiveNoWait();    
  12.         }    
  13.         else if (timeout > 0) {    
  14.             return consumer.receive(timeout);    
  15.         }    
  16.         else {    
  17.             return consumer.receive();    
  18.         }    
  19.     }    
在獲取內容之前先判斷SessionAcknowledgeMode的值,根據是否需要手動控制傳入autoAcknowledge,達到手動控制的效果。



原文地址:http://blog.csdn.net/yueding_h/article/details/54944254


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章