ActiveMq Features--- Consumer Features



Overview

In AMQ4, the choice of a broker performing synchronous or asynchronous dispatch to a consumer has become more configurable. It is now configured as a default value on the connection URI, Connection and ConnectionFactory together with being customizable on a per consumer basis via the Destination Options instead previously just being a transport server setting.

This makes more sense since you want to do async message delivery to slower consumers, but do sync message delivery to faster consumers (to avoid the synchronization and context switching costs of adding another seda queue). The downside to using sync message delivery is that the producer is more likely to block if there is a slow consumer that he is dispatching messages to.

The default setting is dispatchAsync=true which is the best setting for high performance. If you want to deal better with slow consumers you will want to enable this setting. If you want better thoughput and the chances of having a slow consumer are low, you may want to change this to false.

Configuring Async Dispatch at the ConnectionFactory Level

((ActiveMQConnectionFactory)connectionFactory).setDispatchAsync(false);

Configuring Dispatch Async at the Connection Level

Configuring the dispatchAsync setting at this level overrides the settings at the connection factory level.

((ActiveMQConnection)connection).setDispatchAsync(false);

Configuring Dispatch Async at the Consumer Level using the Destination URI

Configuring the dispatchAsync using Destination Options overrides the settings at the connection and connection factory level.

queue = new ActiveMQQueue("TEST.QUEUE?consumer.dispatchAsync=false");
consumer = session.createConsumer(queue);


Background

As well as having a pluggable dispatch policy (e.g. round robin etc), we now support consumer priorities.

This allows us to weight consumers to optimise network hops. For example, you typically want a broker to send messages to regular JMS consumers rather than to other brokers; there's no need to make unnecessary broker-to-broker hops if there are available consumers.

Example

The priority for a consumer is set using Destination Options as follows:

queue = new ActiveMQQueue("TEST.QUEUE?consumer.priority=10");
consumer = session.createConsumer(queue);

The range for assigning priority numbers is from 0 to 127, with 127 being the highest priority and 0 being the default priority.
The way it works is that the broker will simply order any queue consumers according to their priorities and send messages to the highest priority consumers first. 
Once a particular consumer has its prefetch buffer filled up, the broker will begin to dispatch messages to consumers of lower priorities.



































Background

We maintain the order of messages in queues and dispatch them to consumers in order. However if you have multiple JMS Sessions and MessageConsumer instances consuming from the same queue (whether in the same JVM or not), you will loose the guarantee of processing the messages in order; since the messages with be processed concurrently in different threads.

Sometimes its important to guarantee the order in which messages are processed. e.g. you don't want to process the update to an order until an insert has been done; or to go backwards in time, overwriting an newer update of an order with an older one etc.

So what folks have to do in J2EE clusters is often to pin one particular JVM in the cluster to have one consumer on the queue to avoid loosing ordering. The problem with this is that if the particular pinned JVM goes down, no one is processing the queue any more, which can be problem.

Exclusive Consumer

We have a new feature in 4.x called Exclusive Consumer or Exclusive Queues which avoids the end user having to pin anything. The broker will pick a single MessageConsumer to get all the messages for a queue to ensure ordering. If that consumer fails, the broker will auto failover and choose another consumer.

So the effect is a heterogeneous J2EE cluster where each JVM has the same setup and configuration; the broker is choosing one consumer to be the master and send all the messages to it in order until it dies; then you get immediate failover to another consumer.

For those who've struggled with pinning JMS consumers in J2EE clusters you'll immediately realize how useful this is to making clustered, high available distributed services.

Example

An Exclusive Consumer is created using Destination Options as follows:

queue = new ActiveMQQueue("TEST.QUEUE?consumer.exclusive=true");
consumer = session.createConsumer(queue);






























Durable topic subscribers that are offline for a long period of time are usually not desired in the system. The reason for that is that broker needs to keep all the messages sent to those topics for the said subscribers. And this message piling can over time exhaust broker store limits for example and lead to the overall slowdown of the system.

You can always manually unsubscribe inactive durable subscriber using management tools like JConsole or Web Console, but clearly there's more that can be done to help manage systems that use durable subscribers (perhaps coming from environments that they don't control)

Staring with version 5.6 we introduced a few improvements in this area.

Expiring messages

Some applications send message with specified time to live. If those messages are kept on the broker for the offline durable subscriber we need to remove them when they reach their expiry time. Just as we do with queues, now we check for those messages every 30 seconds by default, which can be tuned with the appropriate destination policy. For example, the following entry

<policyEntry topic=">" expireMessagesPeriod="300000"/>

will configure the broker to check for expired messages every 5 minutes.

Removing inactive subscribers

The other thing we can do is to automatically unsubscribe durable subscribers that are not active for some period of time. For that purpose we introduced two new broker properties:

property

default

description

offlineDurableSubscriberTimeout

-1

Amount of time (in milliseconds) after which we remove inactive durable subs. Default -1, means don't remove them

offlineDurableSubscriberTaskSchedule

300000

How often we check (in milliseconds)

An example configuration could look like

<broker name="localhost" offlineDurableSubscriberTimeout="86400000" offlineDurableSubscriberTaskSchedule="3600000">

which means that we check every hour and remove subscriber that has been offline for a day.






















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