As a JMS provider, Message Queue offers a message service that implements the JMS interfaces and that also provides administrative management and control. So far, in illustrating JMS providers, the focus has been mainly on the role of a broker in delivering messages. But in fact, a JMS provider must include many additional elements to provide reliable, secure, and scalable messaging. Figure 1–6 shows the elements that make up the Message Queue message service (the shaded elements in the figure).
As you can see, a full-featured JMS provider is more complex than the basic JMS model might lead one to suspect. The following sections introduce the elements of the Message Queue service shown in Figure 1–6:
At the heart of the message service is the broker, which routes and delivers messages reliably, authenticates users, and gathers data for monitoring performance.
To establish connections to both application clients and administration clients, the broker supports a number of connection services layered on top of several wire protocols.
To route and deliver messages, the broker places incoming messages in their respective destinations and manages message flow into and out of these destinations.
To provide reliable delivery, the broker uses a persistent data store to save state information and persistent messages until they are consumed. Should the broker or the connection fail, the saved information allows the broker to restore the broker’s state and to resume operations.
To provide security for the data being exchanged the broker uses authenticated connections. Optionally data may be encrypted by running over a secure protocol like SSL. The broker also uses and manages a repository that holds information about users and the data or operations they can access. The broker authenticates users who are requesting services and authorizes the operations they want to carry out by looking up information in this repository.
To monitor the system, the broker generates metrics and diagnostic information that an administrator can access to measure performance and to tune the broker. Metrics information is also available programmatically to allow applications or administrators to adjust message flow and patterns to improve performance.
The Message Queue service provides a variety of administrative tools that the administrator can use to configure broker support. For more information, see Built-in Administration Tools.
Client runtime support is provided in libraries that you use when building and running Message Queue clients. You can think of the client runtime as the part of the Message Queue service that enables the client. For example, when client code makes an API call to send a message, code in these libraries is invoked that packages the message bits appropriately for the protocol that will be used to relay the message to a physical destination on the broker.
A JMS provider is only required to support Java clients; however, as Figure 1–6 shows, a Message Queue client can use either the Java API or a proprietary C API to send or receive a message. These interfaces are implemented in Java or C runtime libraries, which do the actual work of creating connections to the broker and packaging the bits appropriately for the connection service being used.
The Java client runtime supplies Java clients with the objects needed to interact with the broker. These objects include connections, sessions, messages, message producers, and message consumers.
The C client runtime supplies C clients with the functions and structures needed to interact with the broker. It supports a procedural version of the JMS programming model. C clients cannot use JNDI to access administered objects, but can create connection factories and destinations programmatically. Message Queue provides the C API to enable legacy C and C++ applications to participate in JMS-based messaging.
There are a number of differences in the functionality provided by these two APIs; these are documented in Java and C Clients.
It is important to remember that the JMS specification is a standard for Java clients only. C support is specific to the Message Queue provider and should not be used in client applications that you plan to port to other providers.
SOAP (Simple Object Access Protocol) allows the exchange of structured data between two peers in a distributed environment. The data exchanged is specified by an XML schema. SOAP message delivery is limited to using the point-to-point domain and does not by itself guarantee reliability.
However, Message Queue Java clients are able to send and receive SOAP messages, encapsulated as JMS messages. By encapsulating a SOAP message in a JMS message and delivering it using the broker, you can take advantage of full featured Message Queue messaging, which guarantees reliable delivery and also allows you to use the publish/subscribe domain. Message Queue provides utility routines that a message producer can use to encapsulate a SOAP message as a JMS message and that a message consumer can use to extract a SOAP message from the JMS message. Message Queue also provides XML schema validation of the encapsulated XML message.
Working with SOAP Messages gives you a more detailed view of SOAP message processing.
The Universal Messaging Service (UMS) and its messaging API provides access to Message Queue from any http-enabled device. As a result, almost any application can communicate with any other application and benefit from the reliability and guaranteed delivery of the Message Queue service.
The UMS, which runs in a web server, is language neutral and platform independent. The UMS serves as a gateway between any non-JMS client application and Message Queue. It receives messages sent using the UMS API, transforms them into JMS messages, and produces them to destinations in the Message Queue broker by way of the broker's connection services. Similarly, it retrieves messages from destinations in the broker, transforms them into text or SOAP messages, and sends the messages to non-JMS clients as requested by the clients through the UMS API.
The simple, language-independent, protocol-based UMS API supports both Web-based and non-Web-based applications, and can be used with both scripting and programming languages. The API is offered in two styles: a simple messaging API that uses a Representational State Transfer (REST)-style protocol, and an XML messaging API that embeds the protocol in a SOAP message header. In both cases, however, the API requires only a single http request to send or receive a message.
The simplicity and flexibility of the UMS API means that AJAX, .NET, Python, Ruby, C, Java, and many other applications can send text message and/or SOAP (with attachment) messages to JMS destinations or receive messages from JMS destinations. For example, Python applications can communicate with .NET applications, iPhone can communicate with Java applications, and so forth.
The Message Queue service offers command line tools that you can use to do the following:
Start and configure the broker.
Create and manage destinations, manage broker connections, and manage broker resources.
Add, list, update, and deleted administered objects in a JNDI object store.
Populate and manage a file-based user repository.
Create and manage a JDBC compliant database for persistent storage.
You can also use a GUI-based administration console to perform the following command-line functions:
Connect to a broker and manage it.
Create and manage physical destinations.
Connect to an object store, add objects to the store, and manage them.
In addition, to these built-in administration tools, Message Queue also supports the Java Management Extensions (JMX) specification for configuring and monitoring brokers, destinations, connection services, and so forth. Using the JMX Administration API, you can perform these administration functions programmatically from within a Java application.
Message Queue brokers can be connected into a broker cluster: a set of brokers that work collectively to perform message delivery between message producers and consumers. Broker clusters add scalability and availability to the Message Queue service, as described briefly in the following sections:
For additional information on broker clusters, see Chapter 4, Broker Clusters
As the number of clients or the number of connections grows, you might need to scale a message service to eliminate bottlenecks or to improve performance. In general, you can scale a message service both vertically (increasing the number of client applications that are supported by a single broker) and horizontally (distributing client applications among a number of interconnected brokers).
Vertical scaling usually requires adding more processing power for a broker and by expanding available resources. You can do this by adding more processors or memory, by switching to a shared thread model, or by running the Java VM in 64 bit mode.
Horizontal scaling is generally achieved using a broker cluster. While it is possible to scale horizontally by simply redistributing clients among additional brokers that are not in a cluster, this approach is appropriate only if your messaging operations can be divided into independent work groups. However, if producer clients must produce messages to be consumed by consumer clients connected to remote brokers, then brokers must work collectively, as part of a broker cluster, to achieve horizontal scaling.
In a broker cluster, each broker is connected to every other broker in the cluster. Brokers can reside on the same host, but more often are distributed across a network. Each broker can route messages from producers to which it is directly connected to consumers that are connected to remote brokers in the cluster.
If you are using the point-to-point domain, you can scale the consumer side by allowing multiple consumers to access a queue. This is a Message Queue feature (the JMS specification defines messaging behavior in the case of only one consumer accessing a queue). When multiple consumers access a queue, the load-balancing among them takes into account each consumer’s capacity and message processing rate.
In addition to providing for message service scalability, broker clusters also provide for message service availability. If one broker in a cluster fails, then other brokers in the cluster are available to continue to provide messaging services to client applications.
Message Queue supports two clustering models that provide different degrees of availability:
Conventional broker clusters. A conventional broker cluster provides message service availability. When a broker or a connection fails, clients connected to the failed broker reconnect to another broker in the cluster. However, messages and state information stored in the failed broker cannot be recovered until the failed broker is brought back online. This can result in an interruption of message delivery.
Enhanced broker clusters. An enhanced broker cluster provides data availability in addition to message service availability. When a broker or a connection fails, another broker takes over the pending work of the failed broker. The failover broker has access to the failed broker's messages and state information. Clients connected to the failed broker reconnect to the failover broker. In an enhanced cluster, as compared to a conventional cluster, a failure results in no interruption of message delivery.
You can also achieve data availability in a conventional cluster by using Sun Cluster software. Sun Cluster software replicates broker data and provides for a hot standby broker to take over the pending work of a failed broker. For details, see the documentation for Sun Cluster Data Service Agent for Message Queue.