views:

42

answers:

2

I'm unclear as to whether there should be a 1-1 or a 1-* relationship between:

  1. Server-Connection Channel and JMS Topic
  2. Server-Connection Channel and Listener
  3. Listener and Topic

Regards the design of our application layer, there is a single MDB that in response to a message, does some work, then publishes messages onto a variety of output topics. The service layer is listening on these output topics.

Currently I have a 1-1-1 between Channel-Listener-Topic, and therefore an instance of JmsConnectionFactory for each publisher (on the app side) and listener (on the service side).

A: 

An MDB in a container creates a pool of MDBs that concurrently process messages. If you simply process and write to the topic you will be fine. With this in mind you do not have a 1-1-1 relationship.

In your MDB just do a JNDI lookup of your TopicConnectionFactory and your Topic and then just write. Look here: http://middleware.its.state.nc.us/middleware/Documentation/en_US/htm/csqzaw09/csqzaw0931.htm

Romain Hippeau
Hi Romain. I'm unclear whether you're suggesting the current design is not 1-1-1 or the what you're suggesting, to use JNDI, makes it 1-1-1. Hopefully the latter in which case I should delete all but one out channels and make the `JmsTopicConnectionFactory` use this one channel. If the former, I'm baffled.
James
What I was trying to say is that you are not 1-1-1 because of pooling. I am not sure what the problem is, All you need to do is create the MDB, which will then listen on the inbound queue. Then your MDB does a JNDI lookup (Which is really just retrieving a Serialized Object, actually two) and then execute your code to publish to the topic. Look at this http://developers.sun.com/appserver/reference/techart/tip1_june_2003.html
Romain Hippeau
+1  A: 

There are a couple of different ways to look at this. From the point of view of your application one connection factory can have many sessions. Each session may have many consumers but units of work are scoped per session, not per consumer. So more than likely you want one connection factory with multiple sessions where each session has a listener on a particular topic. If you have a listener assigned to multiple consumers on a single session, any acknowledge (or COMMIT in a transacted session) commits all messages got or put in that session.

From the WMQ server's point of view, one channel definition can have many running instances. So you only need the one SVRCONN channel defined per app, regardless of how many channel instances it needs to start. Try not to put different apps on the same SVRCONN though because you often want to administer or authorize the apps separately. For example, with apps on separate channels you could easily figure out which app was misbehaving if you suddenly found yourself with 3000 running channels.

For purposes of administration and debugging, I'd probably have one CF for the app side and one CF for the service side. Each would point to a different SVRCONN channel as described above. Inside the app server I'd stick with one topic per session unless it is valid for your app to consume off multiple topics in a single unit of work. In the subscription you can specify a wildcard topic to get all topics below a certain point in the topic tree with a single subscriber.

Just for best practices, I'd also set the CF to use FAILIFQUIESCE to make sure the QMgr can be stopped in an orderly fashion and I'd use SYNCPOINTALLGETS (or a transacted session with explicit commit calls) in order to improve reliability as per the JMS 1.1 spec, sestion 4.4.13 which states:

If a failure occurs between the time a client commits its work on a Session and the commit method returns, the client cannot determine if the transaction was committed or rolled back. The same ambiguity exists when a failure occurs between the non-transactional send of a PERSISTENT message and the return from the sending method. It is up to a JMS application to deal with this ambiguity. In some cases, this may cause a client to produce functionally duplicate messages.

A message that is redelivered due to session recovery is not considered a duplicate message.

The SYNCPOINTALLGETS (a.k.a. SPAG) insures that messages retrieved from the queue are delivered to your app before being committed and permanently removed from the queue. Otherwise if you lose your connection while the QMgr is trying to return a message, it's gone for good. With SPAG set you might see the same message twice as described in the JMS spec, but you'll never drop one.

For more details of the options available to the CF, queue and topic objects, see: Properties of objects in the WebSphere MQ Using Java manual.

WMQ v6.0 is end-of-life as of September 2011 so please be sure to develop using the v7 clients, even if the server is at v6. This will reduce your migration effort next year. Download v7 client here: http://bit.ly/SupportPacMQC7

T.Rob