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.
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-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-3) to process a copy of the message.
MDB-3 have no idea that the message came from the JMS client; they are only aware of a new message published to
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
MDB-2consumes messages sent to
MDB-2sends its own message to
MDB-5both subscribe to
Topic Band receive their own copies message of the sent by
MDB-4does it work and exits.
MDB-5does its work and sends it own message to
MDB-6recieves the message sent to
MDB-6does its work and then sends its own message to
Topic Dand recieve the their own copies of the message sent to
MDB-3does some work and exists.
MDB-7sends a JMS Message to
Topic Ewhich is hosted by a different process on the network.
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.