Message Grouping in Artemis MQ

Message groups in Apache ActiveMQ Artemis allow you to ensure specific sets of messages are processed serially by the same consumer, even in a multi-consumer environment. This tutorial explains the concept and provides examples for sending and receiving messages with groups.

Understanding Message Groups

  • Group ID: Messages within a group share the same group ID. This ID is a property associated with the message and can be set using JMS headers (JMSXGroupID for JMS) or the Artemis-specific property _AMQ_GROUP_ID for native Artemis clients.
  • Serial Processing: Consumers in Artemis can only process one message from a group at a time. Once a message from a group is being processed, other consumers won’t receive messages from that group until the current one is finished.
  • Consumer Affinity: When a consumer starts processing a message from a group, it becomes “pinned” to that group. If the consumer disconnects or crashes, another consumer will be chosen to handle the remaining messages in the same group, ensuring all messages within the group are processed by a single consumer.

Use Cases for Message Groups

  • Order Processing: You might use message groups to handle orders for specific items. Each group could have a unique ID representing the item. This ensures orders for an item are processed sequentially by one consumer, avoiding potential race conditions or inconsistencies.
  • State Management: Message groups can be helpful in managing state updates for entities. Each group could represent the updates for a particular entity, guaranteeing sequential processing of state changes.
  • Transactions: Message groups can be used in conjunction with transactions to ensure messages within a group are delivered and processed atomically (all or none).

Sending Messages with Groups

Here’s how to send messages with groups using both JMS and Artemis native API:

Using JMS:

// ... (connection and session setup)

MessageProducer producer = session.createProducer(queue);

Message message1 = session.createTextMessage("Order for item 123");
message1.setStringProperty(JMSXGroupID, "item_123");

Message message2 = session.createTextMessage("Another order for item 123");
message2.setStringProperty(JMSXGroupID, "item_123");

producer.send(message1);
producer.send(message2);

// ... (clean up resources)

Using Artemis Native API:

// ... (connection and session setup)

ClientMessage message1 = session.createMessage(ClientMessage.TextMessage);
message1.setBody(SimpleBuffer.encodeString("Order for item 123"));
message1.putStringProperty("_AMQ_GROUP_ID", "item_123");

ClientMessage message2 = session.createMessage(ClientMessage.TextMessage);
message2.setBody(SimpleBuffer.encodeString("Another order for item 123"));
message2.putStringProperty("_AMQ_GROUP_ID", "item_123");

session.send(queue, message1);
session.send(queue, message2);

// ... (clean up resources)

In both examples, the messages are assigned the same group ID (“item_123”). Consumers subscribed to the queue will receive these messages in sequence, ensuring all orders for “item_123” are processed by the same consumer.

Receiving Messages with Groups

Consumers don’t need any special configuration to handle message groups. Artemis automatically manages group affinity. Here’s an example consumer using JMS:

// ... (connection and session setup)

MessageConsumer consumer = session.createConsumer(queue);

Message message = consumer.receive();

while (message != null) {
  String groupId = message.getStringProperty(JMSXGroupID);
  System.out.println("Processing message from group: " + groupId);
  // ... (process message content)

  message = consumer.receive();
}

// ... (clean up resources)

The consumer retrieves messages from the queue and checks the JMSXGroupID property to identify the message group. It then processes the message content while ensuring all messages within the same group are handled sequentially.

Important Notes

  • Message groups currently work with queues only, not with topics.
  • Group IDs should be unique identifiers for the specific message grouping logic you’re implementing.

Conclusion

Message groups offer a valuable mechanism for ensuring specific message sets are processed in a particular order within Apache ActiveMQ Artemis. By understanding the concept and using the provided examples, you can leverage this feature to design reliable and predictable message processing in your applications.