DekGenius.com
[ Team LiB ] Previous Section Next Section

11.3 Message Distribution Patterns

Message distribution is built around the concept of a message channel, which happens to be the fundamental idiom behind the JMS API. A message channel provides a named destination for messages. Senders can access the channel to send messages, and receivers can read messages off the channel. It's that simple. In the email world, a message channel consists of the combination of SMTP (for sending and transport) and a mailbox (for receipt). In JMS, a channel is represented as either a Queue or a Topic object, for point-to-point or publish-subscribe messaging, respectively. In a MOM environment, channels can be created and destroyed on the fly, or you can preconfigure them within the MOM system.

11.3.1 Point-to-Point Distribution Pattern

The simplest form of messaging is from one actor to one other actor. This situation applies when using messaging to perform remote procedure calls or to deliver document messages for processing by a particular server. In these cases, it is important that a request be sent once and only once, and that the message be received and processed once and only once. The Point-to-Point Distribution pattern defines this behavior for our applications.

In the ubiquitous purchasing system example, a purchase order should only be sent once, and should only be fulfilled once. This requirement is particularly important when messaging is used to tie together parts of a process: a message sent by an order handler requesting credit card processing should only bill the card once. There are a number of ways to enforce concurrency in distributed applications (see Chapter 10, if you haven't already), but ensuring that the issues don't arise in the first place is always an excellent start.

Figure 11-2 shows a basic point-to-point messaging system. Application 1 sends a message to the message server, which delivers it (some time later) to Application 2, which acknowledges receipt, preventing the messaging server from trying to deliver again later. After some additional processing, Application 2 sends a reply message, which is delivered back to Application 1 by the server.

Figure 11-2. Point-to-point messaging
figs/j2ee_1102.gif

JMS implements point-to-point messaging via the Queue interface. A client places a message on a queue, and another client later removes that message from the queue. Point-to-point distribution can be used to build more complex messaging systems, allowing us to use technology that is intrinsically point-to-point (such as SMTP email) to build more complex systems, as we'll see next.

11.3.2 Publish-Subscribe Pattern

Many enterprise activities require sending the same message, or substantially similar messages, to a large number of recipients. This can certainly be done via point-to-point messaging—as long as the application has a list of recipients for the message, it can loop through and send one to each. But this approach brings its own problems: not only must the application do the work of dispatching a separate message to each individual recipient, it must keep track of the identity of all the recipients. Every application that might send messages to multiple recipients needs a mechanism for tracking the recipient list, and coaxing multiple applications into sending messages to the same list of people becomes a coordination challenge (at best) or nightmare (at worst).

The Publish-Subscribe pattern addresses the maintenance and scalability issues of large numbers of recipients. In this scenario, a source application "publishes" a message to a channel. Recipients then register with the channel to receive messages. Recipients can be added or deleted at the message server level rather than the application level. In JMS, a publish-subscribe channel is called a topic and is implemented via the Topic interface. Figure 11-3 shows a diagram of publish-subscribe messaging.

Figure 11-3. Publish-subscribe messaging
figs/j2ee_1103.gif

In a guaranteed messaging scenario, publish-subscribe can be used to keep a large number of systems synchronized by having each system send a message announcing each change in state. We'll talk more about this with the Control Bus pattern at the end of this chapter. Publish-subscribe can also be used as part of an enterprise management approach: applications publish messages announcing their health (or lack thereof) and respond to command and control messages from a central location. (See Section 7-4 later in this chapter.)

JMS behaviors in a publish-subscribe situation can get fairly subtle. The simple case, where all of the subscribers are connected to the topic at the time a message is sent, is straightforward enough: the subscribers receive the message. But what happens when a subscriber logs on later?

JMS topics can be either persistent or ad hoc; persistent topics are configured at the server level rather than within the Java client itself. Subscriptions to topics can also be configured as either temporary or "durable." Creating a durable subscription allows the client to disconnect and reconnect later without missing the messages sent in between. Normal, nondurable subscriptions only allow a client to receive messages sent while the client is online.

Here's a simple example of connecting to a JMS topic and sending a persistent message to a topic named "greetings".

TopicConnectionFactory factory = // retrieve from JNDI

TopicConnection connection = 
        factory.createTopicConnection(  );
connection.start(  );

TopicSession session = connection.createTopicSession(
        false, Session.CLIENT_ACKNOWLEDGE);

Topic topic = session.createTopic("greetings");

if (topic == null) {
        System.err.println("Unable to load topic.");
        return;
}

TopicPublisher publisher = session.createPublisher(topic);
TextMessage message = session.createTextMessage("Hello!");
publisher.publish(topic, message, DeliveryMode.PERSISTENT, 2, 0);

publisher.close(  );
session.close(  );
connection.close(  );

You will generally use nonguaranteed messaging to implement publish-subscribe for human subscribers. Usenet newsgroups, which are enabled via the NNTP protocol, are a common example. Each newsgroup acts like a JMS topic: a message is sent to the newsgroup itself, and subscribers then connect to the newsgroup and read all of the messages that have been posted. Email-based list servers are an even simpler example: a message is sent to a single address and redistributed to a variety of other addresses.

A private NNTP news server can make a nice, inexpensive publish-subscribe mechanism for interapplication communication, at least where absolute auditability isn't required. News servers have been around for a long time, after all, which means that the underlying software has gotten quite stable.

11.3.3 Malformed Message Channel Pattern

MOM systems usually route undeliverable messages to a dead letter queue that can be monitored by the system administrator. When you're writing code that processes incoming messages, the dead letters aren't really your problem: they are undeliverable, so you never even see them (of course, if your application sends a message that turns out to be undeliverable, you should probably have some way of dealing with the consequences). Malformed messages, however, are your problem. A malformed message is deliverable but nonsensical: the application can't successfully process it. This is a bad situation, since a properly reliable application must provide some way to handle messaging related error conditions.

The Malformed Message Channel pattern provides a solution by specifying a particular destination to which an application can route all badly formatted messages (Figure 11-4). This step allows you to examine the messages manually and determine the source of the problem. Hopefully, malformed messages will be a relatively rare occurrence, so monitoring the channel will not be too onerous.

Figure 11-4. Routing messages to a malformed message channel
figs/j2ee_1104.gif

To implement a malformed message channel in JMS, simply add a Queue or a Topic to your messaging server, and have your application reroute all unreadable messages to the new channel. Most messaging servers provide a mechanism for browsing the contents of a channel, which might be all you need to review the malformed messages. In more complex circumstances, though, you can build an application that alerts the appropriate humans to take corrective action.

The incidence of malformed messages will probably be higher when SMTP is used for messaging. Beyond the ever-present danger of spam (which will manage to find your mailbox if it's anywhere near the Internet), firewalls, strange mail clients, and ill-behaved servers can subtly transform messages. Monitoring these problems becomes correspondingly more important.

    [ Team LiB ] Previous Section Next Section