2014-02-26 72 views
0

有一個'MyConsumer'類接收隊列中的消息並對其進行處理。有兩個要求:如何不使用Spring-JMS確認一條消息?

  1. 如果有一個消息包含無效內容,MyConsumer不應該承認這一點,但可以處理後續的郵件
  2. 時MyConsumer重新啓動

未被消耗的消息將被重新傳遞我用spring-jms嘗試了listener-container支持,但找不到符合第一個要求的解決方案。

我的代碼:MyConsumer

<amq:queue id="destination" physicalName="org.springbyexample.jms.test"/> 

<amq:connectionFactory id="jmsFactory" brokerURL="tcp://localhost:11111"/> 

<bean id="jmsConsumerConnectionFactory" 
     class="org.springframework.jms.connection.SingleConnectionFactory" 
     p:targetConnectionFactory-ref="jmsFactory"/> 

<bean id="jmsConsumerTemplate" class="org.springframework.jms.core.JmsTemplate" 
     p:connectionFactory-ref="jmsConsumerConnectionFactory" 
     p:defaultDestination-ref="destination"/> 

<bean id="jmsMessageListener" class="test.MyConsumer"/> 
<bean id="errorHandler" class="test.MyErrorHandler"/> 

<jms:listener-container container-type="default" 
         connection-factory="jmsConsumerConnectionFactory" 
         error-handler="errorHandler" 
         acknowledge="client"> 
    <jms:listener destination="org.springbyexample.jms.test" ref="jmsMessageListener"/> 
</jms:listener-container> 

類:

@Override 
public void onMessage(Message message) { 
    TextMessage textMessage = (TextMessage) message; 
    try { 
     System.out.println("!!!!!!!!! get message: " + textMessage.getText()); 
    } catch (JMSException e) { 
     e.printStackTrace(); 
    } 
    if (theNumberOfMessageIs(3)) { 
     throw new RuntimeException("something is wrong"); 
    } 
} 

您可能會注意到,在listener-containeracknowledgeclient,實際上它有3個值:

  1. 自動(缺省)
  2. 客戶
  3. 交易

我想所有的人,但沒有一個適合我的要求。我的測試場景:

  1. 製片人把3個消息要排隊
  2. 啓動一個線程來監視隊列中的消息計數,當計數的變化,打印
  3. 啓動消費者,它將從隊列接收消息,並對其進行處理
  4. 等待一段時間,把另外3個消息要排隊

auto

接收每一個消息,無論拋出異常或不

對於client

MyConsumer將承認:

MyConsumer將承認只有當沒有例外onMessage拋出。對於第三條消息,它會拋出異常,隊列中會有一條消息未被消除。但是,當它獲得第4消息,並且不會引發異常,在隊列中的第三個消息將被disapeared

對於transacted

如果MyConsumer拋出的異常,該消息不會被承認和被重新交付幾次。在此之後,該消息從隊列

消失,但它們都不符合要求1.

我想:如果我需要尋找比Spring-JMS,或我的用法是錯誤的其他解決方案?

+0

嗨@Freewind,你有達到你的要求嗎? –

回答

0

autoDefaultMessageListenerContainer是專爲交易而設計的 - 如您發現的那樣,使用自動功能時,消息始終得到確認。您可以使用SimpleMessagseListenerContainer,它可以按照您的要求工作,但它有其他限制;請參閱JavaDocs。

client這就是JMS的工作方式,當你檢查#4,#3時也會自動檢查 - 看到Message JavaDocs。客戶端模式用於減少確認流量(通過每10條消息進行確認)。

transacted這是代理的功能,您可以配置AMQ在一些重試次數後將錯誤消息發送到死信隊列。

您需要一些過程將消息從DLQ移回主隊列以供稍後重試(可能在重新啓動時進行初始化時)。

0

使用WMQ,您可以使用BackOut功能使用BOTHRESH和BOQNAME隊列配置參數來實現此需求,其中BOTHRESH定義嘗試使用消息的次數,然後在參數BOQNAME中定義QUEUE的名稱,表明您的消息將被重新傳遞。在這種情況下,您可以使用DLQ QUEUE,您可以在一段時間後將消息移動到主QUEUE,或者將主QUEUE作爲DLQ QUEUE使消息在消費者中旋轉。 希望有所幫助。