Clustered Clients and JMS Distributed Destinations

Recently a customer asked me about a JMS problem they've been experiencing when using Uniform Distributed Topics (UDT). I explain the problem below but essentially the application consuming the JMS messages was itself a clustered client, and thus getting a message per instance of the application across the cluster.

The Problem
The problem was they have a number of applications deployed to a cluster as clients consuming from the distributed topic. Each instance of the application is treated as a consumer and thus getting multiple message instead of the desired one per application across the cluster. Now don't get me wrong, the customer was not complaining that JMS or distributed queues needed to be changed, but how could they get the functionality they wanted while still enjoying the higher availability and scalability a UDT afforded them. One thing to note is if the operations being performed on the messages were idempotent this wouldn't have been as serious even though it was processed multiple times, the result would have been the same (albeit a little ugly!).

The image below describes the situation the customer was trying to solve.
JMSArchitecture%20-%20current.jpg

The Target
The goal was to have a messaging system to the guarantee delivery while also being resilient. Each application, whilst deployed across the cluster should only get one message.

JMSArchitecture-desired.jpg
This diagram shows the proposed messaging architecture.
A message coming into the Uniform Distributed Destination (UDD) is sent, in some load balancing fashion, to only one instance of the application. The load balancing might be multiplexed across application or across cluster nodes and then across the instances of the application on that node.


Proposed Solution

The main problem with the current architecture is the UDT which is directly handling the incoming the messages and from which the applications are directly subscribing to. This naturally broadcasts the messages across all members indiscriminately, irrespective of application.

The UDT can be replaced with a UDQ to which external messages are published. The UDQ will load balance these incoming messages to one and only one of the managed servers. A local Message-driven Bean deployed to the cluster can listen on the UDQ (an instance of which will be deployed to each of the managed servers). Its sole job is to publish to a local-only JMS Topic to which the applications are listening. This is shown logically below.
JMSArchitecture%20-%20proposed.jpg

It is important the MDB is transactional, to ensure it succeeds in putting the message into the local topic, or on failure the transaction is rolled back and thus the message is ready for another attempt. The local Topic must have a unique name and no global JNDI name. Instead a local JNDI name is provided which is the same across the cluster (and thus the MDB publishes the messages to a Topic with the same same name irrespective of its location in the cluster).

I have prototype this solution in WebLogic Server 10gR3 using EJB 3.0 on a two node cluster, and am happy to share the project should someone be interested enough.

Reference : http://blogs.oracle.com/BrettLomas/2009/02/clustered_clients_and_jms_dist_1.html

0 comments:

Post a Comment