ActiveMQ第六彈:設定多個並行的消費者

無敵西瓜發表於2014-03-23

訊息佇列本來就是一種經典的生產者與消費者模式。生產者向訊息佇列中傳送訊息,消費者從訊息佇列中獲取訊息來消費。

img_0fe8379de75917e2a6cf8c3e55d44630.png

訊息的傳送一般由一個代理來實現的,那就是Message broker(即訊息代理)。Message broker有兩大職責,一是訊息路由,二是資料轉換。這就好比A給B寄信,如果不使用郵局的話,就要自己想辦法送達,費時費力,而通過郵局的話,只要B的地址在郵局中註冊過,那麼天涯海角也能送達。這裡的郵局扮演的角色就像訊息系統中的Message broker。

img_5e4597b91f0d1084061ab5e0b108fe0c.png

眾所周知,訊息佇列是典型的’send and forget’原則的體現,生產者只管傳送,不管訊息的後續處理。為了最大效率的完成對訊息佇列中的訊息的消費,一般可以同時起多個一模一樣的消費者,以並行的方式來拉取訊息佇列中的訊息。這樣的好處有多個:

  1. 加快處理訊息佇列中的訊息。

  2. 增強穩定性,如果一個消費者出現問題,不會影響對訊息佇列中訊息的處理。

img_fde96d07ea2242d1157aa80114e1c2cc.png

使用Spring JMS來配置多個Listener例項其實也相當簡單,只需要配置下MessageListenerContainer就行。

1
2
3
4
5
6
<bean class="org.springframework.jms.listener.SimpleMessageListenerContainer">
    <property name="connectionFactory" ref="connectionFactory"/>
    <property name="destinationName" value="${jms.queue.name}"/>
    <property name="messageListener" ref="messageReceiver"/>
    <property name="concurrentConsumers" value="4"/>
</bean>

多配置一個屬性concurrentConsumers,設定值為4,就是同時啟動4個Listener例項來消費訊息。

使用MessageSender來傳送100條訊息,可以檢查訊息處理的順序會發生變化。

1
2
3
    for (int i = 0; i < 100; i++) {
        messageSender.send(String.format("message %d",i));
    }

1
2
3
4
5
6
7
8
9
...
Received: message 4
Received: message 7
Received: message 6
Received: message 5
Received: message 8
Received: message 10
Received: message 9

除了設定一個固定的Listener數量,也可以設定一個Listener區間,這樣MessageListenerContainer可以根據訊息佇列中的訊息規模自動調整並行數量。

1
2
3
4
5
6
    <bean class="org.springframework.jms.listener.SimpleMessageListenerContainer">
        <property name="connectionFactory" ref="connectionFactory"/>
        <property name="destinationName" value="${jms.queue.name}"/>
        <property name="messageListener" ref="messageReceiver"/>
        <property name="concurrency" value="4-8"/>
    </bean>

這次使用的是concurrency屬性,4-8表示最小併發數是4,最大併發數為8,當然也可以給一個固定值,比如5,這樣就相當於concurrentConsumers屬性了。

本章中的完整原始碼可從完整程式碼可從https://github.com/huangbowen521/SpringJMSSample下載。


相關文章