So far we have described the elements of message-oriented middleware and the use of JMS as a way of adding portability to MOM applications. It now remains to describe how Message Queue implements the JMS specification and to introduce the features and tools it uses to provide reliable, secure, and scalable messaging service.
First, like many JMS provider, Message Queue can be used as a stand-alone product or it can be used as an enabling technology, embedded in a J2EE application server to provide asynchronous messaging. Chapter 5, Message Queue and J2EE describes the role Message Queue plays in J2EE in greater detail. Unlike other JMS providers, Message Queue has been designated as the JMS reference implementation. This designation attests to the fact that Message Queue is a correct and complete JMS implementation. It also guarantees that the Message Queue product will remain current with any future JMS revisions and extensions.
As a JMS provider, Message Queue offers a messaging service that implements the JMS interfaces and that provides administrative services and control. So far, in illustrating JMS providers, the focus has been mainly on the role of the broker in relaying messages. But in fact, a JMS provider must include many elements in addition to the broker to provide reliable, secure, scalable messaging. Figure 1–6 shows the elements that make up the Message Queue message service. These include a variety of connection services (supporting different protocols), administrative tools, and data stores for messaging, monitoring, and user information. The Message Queue service itself includes all elements marked in gray in the figure.
As you can see, a full-featured JMS provider is more complex than the basic JMS model would lead one to suspect. The following sections describe the elements of the Message Queue service shown above. These elements can be divided into three categories: the broker, client runtime support, and administration.
As shown in Figure 1–6 both application clients and administration clients can connect to the broker. The JMS specification does not dictate that providers implement any specific wire protocols. Message Queue services, used by application clients and administration clients to connect to the broker, are currently layered on top of TCP, TLS, HTTP, or HTTPS protocols. (Services layered on top of HTTP allow messages to pass through firewalls.)
Services that provide JMS support and allow clients to connect to the broker (jms, ssljms, http, or https) have a service type of NORMAL and are layered on top of TCP, TLS, HTTP, or HTTPS protocols.
Services that allow administrators to connect to the broker ( admin, ssladmin) have a service type of ADMIN and are layered on top of TCP or TLS protocols.
By default, when you start the broker, jms and admin services are up and running. Additionally, you can configure a broker to run any or all of these connection services. Each service supports specific authentication and authorization (access control) features and each service is multi-threaded, supporting multiple connections.
Should a connection fail, the Message Queue service can automatically retry connecting the client to the same broker or to a different broker if this feature is enabled. For more information, see the description of the automatic reconnect feature in Appendix B, Message Queue Features
Clients can configure connection runtime support when they create the connection factory from which they obtain their connections. Options allow you to specify which brokers to connect to, how to handle reconnection, message flow control, and so on. For additional information about how connections can be configured, see Connection Factories and Connections.
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 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 store to save state information and persistent messages until they are received. Should the broker or the connection fail, the saved information allows the broker to restore the broker’s state and to retry 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 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 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 Administration.
Client runtime support is provided in libraries that you link with when building Message Queue clients. You can think of the client runtime as the bit of the Message Queue service that becomes part of 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 the 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 or a provider-specific 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 requested.
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.
The Message Queue service provides a 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.
Message Queue Java clients are also able to send and receive SOAP messages, wrapped as JMS messages. 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 scheme.
Sun SOAP processing is currently limited to using a point-to-point model and does not guarantee reliability. By wrapping a SOAP message in a JMS message and routing it using the broker, you can take advantage of full featured Message Queue messaging which guarantees reliable delivery and allows you to use the topic as well as the point-to-point domain. Message Queue provides utility routines that a message producer can use to wrap a SOAP message into a JMS message and that a message consumer can use to extract a SOAP message from the JMS message.
Working with SOAP Messages gives you a more detailed view of SOAP message processing.
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.
As the number of clients or the number of connections grows, you may need to scale the message service to eliminate bottlenecks or to improve performance. The Message Queue message service offers a number of scaling options, depending on your needs. These may be conveniently sorted into the following categories:
Vertical scaling is achieved by adding more processing power 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.
If you are using the point-to-point domain, you can scale the consumer side by allowing multiple consumers to access a queue. Using this approach, you can specify the maximum number of active and backup consumers. The load-balancing mechanism also takes into account a consumer’s current capacity and message processing rate. This is a Message Queue feature. (The JMS specification defines messaging behavior if only one consumer is accessing a queue; behavior for queues allowing more than one consumer is provider-specific. The Message Queue developer guides provide more information about this scaling option.)
Stateless horizontal scaling is achieved by using additional brokers and redistributing existing clients to these brokers. This approach is easy to implement, but it is appropriate only if your messaging operations can be divided into independent work groups.
Stateful horizontal scaling is achieved by connecting brokers into a cluster. In a broker cluster, each broker is connected to every other broker in the cluster as well as to its local application clients. Brokers can be on the same host or distributed across a network. Information about destinations and consumers is replicated on all the brokers in the cluster. Updates to destinations or subscribers is also propagated Each broker can therefore route messages from producers to which it is directly connected to consumers that are connected to other brokers in the cluster. In situations where backup consumers are used, if one broker or connection fails, messages sent to inaccessible consumers can be forwarded to a backup consumers on another broker.
In the event of broker or connection failure, state information about persistent entities (destinations and durable subscriptions) can get out of sync. For example, if a clustered broker goes down and a destination is created on another broker in the cluster, when the first broker restarts, it will not know about the new destination. Message Queue uses two different models to resolve this problem: conventional clustering and high availability clustering.
Using conventional clustering, you set broker properties to designate one broker in the cluster to be the master broker. This broker is responsible for tracking all changes to destinations and durable subscriptions in a master configuration file and for updating brokers in the cluster that are temporarily offline.
When using a master broker, Message Queue only provides service availability, not data availability in the case of broker or connection failure. For example, if a clustered broker becomes unavailable, any persistent messages held by that broker become unavailable until that broker recovers. To get data availability you can use a SunCluster Message Queue agent or you can use high availability clustering, described next. (In the SunCluster case, a persistent store is kept on a shared file system. If a broker fails the Message Queue agent on a second node starts a broker that takes over the shared store. Clients are reconnected to that broker, thereby getting both continuous service and access to persistent data.)
Using high availability clustering, you set broker properties to specify a highly available database that is shared by all brokers in the cluster. The shared store holds updated information about the state of each broker in the cluster. If one broker fails, another broker assumes ownership of the failed broker's persistent state (in the shared store) and provides uninterrupted service to the failed broker's clients.
For additional information, see Chapter 4, Broker Clusters