Статьи

ActiveMQ — Сеть брокеров объяснил (часть третья)


Теперь, когда мы поняли основы сетевого коннектора ActiveMQ в
части 1 и
части 2 этой серии блогов, в этой части 3 мы рассмотрим, как балансировка нагрузки ActiveMQ используется для потребителей, которые подключаются к сети брокеров.

Вступление


Параллельные потребители используются, когда сообщения в очереди могут обрабатываться не по порядку и обычно для повышения пропускной способности.
Брокер ActiveMQ распределяет сообщения круговым способом среди потребителей, чтобы распределить потребление сообщений между параллельными потребителями, если потребитель не указан как
исключительный

Давайте посмотрим на следующий пример, где три потребителя одновременно обрабатывают сообщения из очереди foo.bar.
Производитель ставит в очередь 60 сообщений, которые обрабатываются тремя потребителями (по 20 каждый) в циклическом порядке.

Запустить трех одновременно работающих потребителей в очереди foo.bar

Ashwinis-MacBook-Pro:example akuntamukkala$ pwd
/Users/akuntamukkala/apache-activemq-5.8.0/example


Ashwinis-MacBook-Pro:example akuntamukkala$ ant consumer -Durl=tcp://localhost:61616 -Dtopic=false -Dsubject=foo.bar -DparallelThreads=3 -Dmax=20
Произвести 60 сообщений
Ashwinis-MacBook-Pro:example akuntamukkala$ ant producer -Durl=tcp://localhost:61616 -Dtopic=false -Dsubject=foo.bar -Dmax=60


На следующем снимке экрана 3 потребителя обрабатывают сообщения из очереди foo.bar.
60 сообщений были помещены в очередь и удалены из очереди. 

Как показано ниже, 20 сообщений были обработаны каждым из потребителей. 

Следующая выдержка из журнала показывает, что сообщения распределены среди трех потребителей …
[java] [Thread-3] Received: 'Message: 1 sent at: Tue Mar 04 13:46:53 IST 2014  ...' (length 1000)
[java] [Thread-2] Received: 'Message: 0 sent at: Tue Mar 04 13:46:53 IST 2014  ...' (length 1000)
[java] [Thread-1] Received: 'Message: 2 sent at: Tue Mar 04 13:46:53 IST 2014  ...' (length 1000)
[java] [Thread-3] Received: 'Message: 4 sent at: Tue Mar 04 13:46:53 IST 2014  ...' (length 1000)
[java] [Thread-2] Received: 'Message: 3 sent at: Tue Mar 04 13:46:53 IST 2014  ...' (length 1000)
[java] [Thread-1] Received: 'Message: 5 sent at: Tue Mar 04 13:46:53 IST 2014  ...' (length 1000)
[java] [Thread-3] Received: 'Message: 7 sent at: Tue Mar 04 13:46:53 IST 2014  ...' (length 1000)
[java] [Thread-2] Received: 'Message: 6 sent at: Tue Mar 04 13:46:53 IST 2014  ...' (length 1000)
[java] [Thread-1] Received: 'Message: 8 sent at: Tue Mar 04 13:46:53 IST 2014  ...' (length 1000)

[java] [Thread-3] Received: 'Message: 10 sent at: Tue Mar 04 13:46:53 IST 2014 ...' (length 1000)


Теперь, когда мы увидели, как параллельные потребители работают с одним брокером, теперь мы рассмотрим, как они работают, когда потребители распределены по сети брокеров. 

Местные против удаленных потребителей


Давайте рассмотрим, как ActiveMQ обрабатывает локальных и удаленных потребителей с помощью конфигурации, показанной на рисунке ниже. 


Consumer-1 и Consumer-2 получают сообщения из очереди foo.bar в Broker-1 и Broker-2 соответственно.
Broker-1 установил сетевой соединитель с Broker-2 для пересылки сообщений в очереди. Производитель помещает сообщения в очередь foo.bar на Broker-1

Давайте посмотрим это в действии

  • Отредактируйте конфигурацию Broker-1 /Users/akuntamukkala/apache-activemq-5.8.0/bridge-demo/broker-1/conf/activemq.xml и откройте сетевой соединитель для Broker-2 и перезапустите Broker-1 и Broker-2
         <networkConnectors>
                <networkConnector
                        name="T:broker1->broker2"
                        uri="static:(tcp://localhost:61626)"
                        duplex="false"
                        decreaseNetworkConsumerPriority="false"
                        networkTTL="2"
                        dynamicOnly="true">
                        <excludedDestinations>
                                <queue physicalName=">" />
                        </excludedDestinations>
                </networkConnector>
                <networkConnector
                        name="Q:broker1->broker2"
                        uri="static:(tcp://localhost:61626)"
                        duplex="false"
                        decreaseNetworkConsumerPriority="false"
                        networkTTL="2"
                        dynamicOnly="true">
                        <excludedDestinations>
                                <topic physicalName=">" />
                        </excludedDestinations>
                </networkConnector>
        </networkConnectors>

  • Start local consumer, Consumer-1
 Ashwinis-MacBook-Pro:example akuntamukkala$ ant consumer -Durl=tcp://localhost:61616 -Dtopic=false -Dsubject=foo.bar 
  • Start remote consumer, Consumer-2
Ashwinis-MacBook-Pro:example akuntamukkala$ ant consumer -Durl=tcp://localhost:61626 -Dtopic=false -Dsubject=foo.bar
  • Start producer on Broker-1 to enqueue 100 messages
Ashwinis-MacBook-Pro:example akuntamukkala$ ant producer -Durl=tcp://localhost:61616 -Dtopic=false -Dsubject=foo.bar -Dmax=100
Screenshot showing Broker-1’s queues:
Let’s look at the consumers to see how the messages have been divvied out.
As you may notice, ActiveMQ broker dispatches the messages equally to local consumer over the remote consumer giving them the same priority. 
The remote consumer, Consumer-2 is only broker 1 hop away which is less than configured networkTTL value of 2.
This leads to suboptimal routes especially when brokers are connected such that multiple routes are possible between producers and consumers. It is preferable to dispatch to local consumers over remote consumers in order to ensure shortest path between producers and consumers. 
ActiveMQ provides a way to configure the priority between local consumer and remote consumer using the property decreaseNetworkConsumerPriority on the network connector.
By default, this value is false and hence the local and remote brokers were treated alike. 
If we repeat the above steps after changing the decreaseNetworkConsumerPriority=»true» 
then we find that local consumer, Consumer-1 is given preference over remote consumer, Consumer-2 which is 1 broker hop away. 

ActiveMQ intelligently figures out shortest path in a network of brokers between message producers and consumers. 

Please read the following link to gain further understanding of optimal routing by ActiveMQ.

This concludes part 3 of this series where we saw how to differentiate local and remote consumers to assist ActiveMQ determine most optimal path between message producers and consumers. 

As always your comments are very welcome. 
Stay tuned for part 4 where we will go over load balancing remote concurrent consumers…