How many times are topic messages delivered ?
This may seem to be a trivial question, but when clustering is involved, it's not.
JEE has strong support for clustering, but many JEE specifications do not define what is actually supported, and leaves room for application server specific features. This is the case for JMS in the various specifications involved (JMS, JEE, EJB, JCA).
The question is how many times are messages delivered and treated (e.g. once per cluster or once per application server)?
Note that to simplify the problem I will not address selectors, delivery modes or acknowledgement considerations. I will also only address business application clustering, not JMS implementation clustering.
When Queues are used the situation is quite clear, the message is delivered once whether you use clustering or not. But when Topics are used, there is no simple answer.
When a message is sent to a Topic, each currently active non-durable subscriber should receive the message once. If the receiving application is clustered, the message should be received one time per application server instance in the cluster. That's what we get with JBoss 4.2.3.
This is actually not always the case. One example with WebSphere 6.1:
- A business application is deployed to a cluster of two application servers
- The JMS message engine is also deployed to a cluster of two application servers
- The application uses a MDB with a non-durable subscription to a Topic
- A message is sent to that Topic
If the two clusters are different, then the message is received by one MDB on each application instance, so the message is treated twice. But if the two clusters are actually the same, then the message is only received by one MDB instance on the application server where the message engine instance runs, so the message is treated once instead of twice. Painful.
For reliability considerations, enterprise applications often use durable subscriptions to Topics. This makes the situation even more complicated.
Durable subscriptions are identified by a subscription name. This defines the number of deliveries, meaning that the message should be delivered once per distinct subscription name.
JMS offers three ways to receive messages: Message Driven Beans (MDB), synchronous receptions using MessageConsumer:receive and explicit message listeners using MessageConsummer:setMessageListener. We won't address message listeners as they are forbidden on the server side by the JEE specifications.
When doing synchronous receptions or message listeners, the durable subscription name is managed by the developper using Session:createDurableSubscriber. This way it is possible (it is actually required by the JMS specification) to give a different name per application instance in the cluster to choose the number of times the messages are received.
With MDB we cannot officially manage the subscription name, so there is not portable control of the number of messages delivery. Note that we cannot manage the client ID either. In more details, both client ID and subscription name are valid parameters as per the JCA specification, but they are not according to the EJB specification.
We need precise, portable and cluster compliant semantics about the number of time JMS messages get delivered.