Tomitribe supports many organizations that use Message-Driven Beans in production with TomEE. This post is derived from experience working with those organizations to improve their system performance and software architecture.
Previously we published a MDB tutorial followed by a deeper dive in the article “MBD-to-MDB Messaging: Harness the Power of the River Delta“. This week we’ll provide an illustrated example of how MDBs can work together to create flexible and powerful messaging system.
JMS
The Java Messaging Service (JMS) is a standard for sending messages between clients using a messaging broker. The concepts behind JMS, queues, and topics are explained in simple English in the short post, “5 Minutes or Less: ActiveMQ with JMS Queues and Topics”. If you don’t know much about JMS you should read the introduction of that article. There is also a quick tutorial with running example code you can try. The important thing to understand is that JMS is the foundation of Message-driven Beans.
An Illustrated Messaging System
The diagram below illustrates a complete messaging consisting of a JMS broker, topics or queues, a MDB container, and different types MDBs each with a pool of instances.
In the above diagram a stand-alone JMS client sends a message to the ActiveMQ broker addressed to Topic A
. ActiveMQ forwards the message to all listeners of Topic A
which include MDB-1
and MDB-3
. MDB-1
and MDB-3
are different MDB components with different functionality, but they are both listening to Topic A
. When a message is published to Topic A
, a copy is forwarded to the MDB Container which selects one MDB instance of each type (i.e. MDB-1
and MDB-3
) to process a copy of the message. MDB-1
and MDB-3
have no idea that the message came from the JMS client; they are only aware of a new message published to Topic A
.
After receiving the message a MDB does some work and then waits for the next message. MDBs are stateless so the processing of any message does not impact the processing of subsequent messages. a MDB may also publish its own messages to specific topics or queues. This allows MDBs to form decoupled, asynchronous networks where each MDB runs independent of other MDBs but messages are exchanged among them via topics and queues.
In the above diagram, you can see how several MDBs in the same MDB container can exchange messages among themselves.
- A JMS client, in some other process on the network, sends a message to
Queue A
. MDB-2
consumes messages sent toQueue A
.MDB-2
sends its own message toTopic B
.MDB-4
andMDB-5
both subscribe toTopic B
and receive their own copies message of the sent byMDB-2
.MDB-4
does it work and exits.MDB-5
does its work and sends it own message toQueue C
.MDB-6
recieves the message sent toQueue C
.MDB-6
does its work and then sends its own message toTopic D
.MDB-3
andMDB-7
subscribe toTopic D
and recieve the their own copies of the message sent toTopic D
.MDB-3
does some work and exists.MDB-7
sends a JMS Message toTopic E
which is hosted by a different process on the network.
Conclusion
Message-driven beans can form the foundation of a very powerful, asynchronous, loosely-coupled architecture where each component has many instances each of which can consume a message from queue or topic. The ability to send messages from one MDB to the next allows the system enormous flexibility because messages are sent to specific topics and queues not to specific components. You can change the topics and queues that MDBs subscribe to as well as the ones they send messages to, this creates an incredibly flexible system where components can be added, replaced and removed without disrupting the work of the rest of the system.