18.11. Message Grouping
18.11.1. About Message Grouping
A message group is a set/group of messages which share certain characteristics:
- All messages in a message group are grouped under a common group id. This means that they can be identified with a common group property
- All messages in a message group are serially processed and consumed by the same consumer irrespective of the number of customers on the queue. This means that a specific message group with a unique group id is always processed by one consumer when the consumer opens it. If the consumer closes the message group the entire message group is directed to another consumer in the queue
Important
Message groups are especially useful when there is a need for messages with a certain value of the property (group id) to be processed serially by a single consumer.
18.11.2. Using HornetQ Core API on Client Side
The property
_HQ_GROUP_ID
is used to identify a message group in HornetQ Core API on client side. To pick a random unique message group identifier you can also set the auto-group
property as true
on the SessionFactory.
18.11.3. Configuring Server for Java Messaging Service (JMS) Clients
The property
JMSXGroupID
is used to identify a message group for Java Messaging Service (JMS) clients. If you wish to send a message group with different messages to one consumer you can set the same JMSXGroupID
for different messages:
Message message = ... message.setStringProperty("JMSXGroupID", "Group-0"); producer.send(message); message = ... message.setStringProperty("JMSXGroupID", "Group-0"); producer.send(message);The second approach is to set the
auto-group
property to true
on the HornetQConnectonFactory
. The HornetQConnectionFactory
will then pick up a random unique message group identifier. You can set the auto-group
property in server configuration files (standalone.xml
and domain.xml
) as follows:
<connection-factory name="ConnectionFactory"> <connectors> <connector-ref connector-name="netty-connector"/> </connectors> <entries> <entry name="ConnectionFactory"/> </entries> <auto-group>true</auto-group> </connection-factory>An alternative to the above methods is to set a specific message group identifier through the connection factory. This will in turn set the property
JMSXGroupID
to the specified value for all messages sent through this connection factory. To set a specific message group identifier on the connection factory, edit the group-id
property in server configuration files (standalone.xml
and domain.xml
) as follows:
<connection-factory name="ConnectionFactory"> <connectors> <connector-ref connector-name="netty-connector"/> </connectors> <entries> <entry name="ConnectionFactory"/> </entries> <group-id>Group-0</group-id> </connection-factory>
18.11.4. Clustered Grouping
Important
Clustered grouping is provided as technology preview only. It is not supported for use in a production environment and may be subject to significant future changes.
Clustered grouping follows a different approach relative to normal message grouping. In a cluster, message groups with specific group ids can arrive on any of the nodes. It is important for a node to determine which group ids are bound to which consumer on which node. Each node is responsible for routing message groups correctly to the node which has the consumer processing those group ids irrespective of where the message groups arrive by default. Once messages with a given group id are sent to a specific consumer connected to the given node in the cluster, then those messages are never sent to another node even if the consumer is disconnected.
This situation is addressed by a grouping handler. Each node has a grouping handler and this grouping handler (along with other handlers) is responsible for routing the message groups to the correct node. There are two types of grouping handlers namely
local
and remote
.
The local handler is responsible for deciding the route which a message group should take. The remote handlers communicate with the local handler and work accordingly. Each cluster should choose a specific node to have a local grouping handler and all the other nodes should have remote handlers.
Warning
If message grouping is used in cluster, it breaks if the server with configured remote grouping handler fails. Setting up backup for remote grouping handler also does not have affect.
You can configure "local" and "remote" grouping handlers in server configuration files (
standalone.xml
and domain.xml
) as follows:
<grouping-handler name="my-grouping-handler"> <type>LOCAL</type> <address>jms</address> <timeout>5000</timeout> </grouping-handler> <grouping-handler name="my-grouping-handler"> <type>REMOTE</type> <address>jms</address> <timeout>5000</timeout> </grouping-handler>The "timeout" attribute ensures that a routing decision is made quickly within the specified time. If a decision is not made within this time an exception is thrown.
The node which initially receives a message group takes the routing decision based on regular cluster routing conditions (round-robin queue availability). The node proposes this decision to the respective grouping handler which then routes the messages to the proposed queue if it accepts the proposal.
If the grouping handler rejects the proposal, it proposes some other route and the routing takes place accordingly. The other nodes follow suite and forward the message groups to the chosen queue. After a message arrives on a queue it is pinned to a customer on that queue.
18.11.5. Best Practices for Clustered Grouping
Some best practices for clustered grouping are as follows:
- If you create and close consumers regularly make sure that your consumers are distributed evenly across the different nodes. Once a queue is pinned, messages are automatically transferred to that queue regardless of removing customers from it
- If you wish to remove a queue which has a message group bound to it, make sure the queue is deleted by the session that is sending the messages. Doing this will ensure that other nodes will not try to route messages to this queue after it is removed
- As a failover mechanism always replicate the node which has the local grouping handler