9 Best Practices for JMS Beginners and Advanced Users

Learn about the recommended and best practices for JMS beginners and advanced JMS users of Oracle WebLogic Server. The following topics include targeting, integration options, understanding URLs, high availability (HA), and tuning for WebLogic Server:

Configuration Best Practices

Configuring a JMS application includes configuring persistent stores, JMS servers, JMS modules, and JMS resources within JMS modules. JMS resources within modules include JMS connection factories, JMS standalone destinations, or JMS distributed destinations. Configuring a SAF application is very similar except that it substitutes SAF Agents for JMS Servers and imported destinations for distributed destinations.The following sections outline the basic procedure:
  1. Configure JMS Servers and Persistent Stores

  2. Configure JMS Quotas and Paging

  3. Configure a JMS Module

  4. Configure JMS Resources

  5. Configure SAF Agents, Stores, and Imported Destination

Configure JMS Servers and Persistent Stores

Before you start configuring JMS servers and persistent stores, consider the following:

  • Destinations, connection factories, and other JMS resources are configured separately from their host JMS servers and persistent stores. The best practice steps for configuring JMS resources will be described later.

  • WebLogic JMS distributed destination features require a working WebLogic cluster.

  • There are two types of clustered JMS configuration:

    • Cluster-targeted JMS servers and stores provide simplified configuration, simplified HA, and the ability to dynamically scale resources. JMS servers, stores, and distributed destination members are automatically added as the cluster size increases without any configuration change required.

      Note:

      Cluster-targeted JMS is the only available JMS option if you want to leverage WebLogic dynamic clusters instead of a configured cluster. See Simplified JMS Cluster and High Availability Configuration.

    • Individually configured JMS HA consists of a set of individually configured JMS servers and stores that are in turn targeted to migratable targets within a cluster. This option primarily exists for compatibility with earlier versions.

  • If you are not using a cluster, then you may want to reconsider and use a cluster of at least size one and use distributed destinations instead of standalone destinations. This helps “future-proof" your application for future HA and scaling support, as it ensures configuration and applications are easily capable of expanding to multiple servers. Leveraging a cluster is best done in very early configuration and application design stages as it is a difficult process to convert a non-clustered application and configuration into a clustered topology.

Note:

For high availability and scaling, Oracle recommends targeting the JMS artifacts to a cluster along with appropriate high availability configuration settings instead of using migratable targets.

Use the following steps to configure JMS servers and persistent stores in a cluster.

Steps for setting up cluster-targeted JMS:

  1. Create a custom store and target it to the cluster. See Simplified JMS Cluster and High Availability Configuration. Ensure the store is configured to persist your data safely as described in Ensure Your Data is Persisted Safely.

  2. Configure a JMS server and target it to the same cluster, plus configure the JMS server to reference the store that was created in step 1. Multiple JMS servers can reference the same store.

Steps for setting up individual-configured JMS in a cluster:

  1. Create a custom store on each WebLogic server in the cluster. Target each store to the default migratable target on its server or to a custom migratable target. See Service Migration in Administering Clusters for Oracle WebLogic Server. Ensure the store is configured to persist your data safely as described in Ensure Your Data is Persisted Safely.

    Note:

    It is recommended to use custom stores that provide more flexibility in tuning and administration. In addition, the default file store is not migratable between JVMs. Only custom stores are migratable.

  2. Configure a JMS server on each WebLogic server. Configure the JMS server to reference the store for the server that was created in step 1. Target the JMS server to the same target that was used for the store. Multiple JMS servers can reference the same store.

Configure JMS Quotas and Paging

Configure a message and/or byte quota on the JMS server. There is no default quota, so configuring one helps protect against out-of-memory conditions. Rule of thumb: conservatively assume that each message consumes at least 512 bytes of memory even if it is paged out.

Note:

Persistent JDBC store messages, persistent file store messages, and non-persistent messages are all fully cached in JVM memory until they page out. And any type of message has a header that remains in JVM memory even after the message is paged out.

Although JMS paging is enabled by default, verify that the default behavior is valid for your environment. See Paging Out Messages To Free Up Memory in Tuning Performance of Oracle WebLogic Server.

Configure a JMS Module

A JMS module encapsulates JMS connection factory and destination configuration. It is a best practice to configure a system module and system module subdeployment for each homogenous set of JMS servers within a cluster. This maintains a simple one to one correspondence between JMS module resource configuration, JMS module subdeployment, and JMS server configuration.

A homogenous set of JMS servers is either:

  • A single cluster-targeted JMS server with its store’s distribution-policy set to Distributed.

  • A single cluster-targeted JMS server with its store’s distribution-policy set to Singleton.

  • A set of one or more individually configured JMS servers.

Different JMS configurations can co-exist in the same cluster scope as long as they use different configuration names and different JNDI names.

Specifically:
  1. Create a system module. Target it to a single cluster (if using clusters) or a single WebLogic Server instance. You must always target the module even when leveraging subdeployments.

    Note:

    System modules are the preferred way to configure JMS resources. The alternatives, deployable modules and JMS resource definitions, are not recommended. Deployable modules are a deprecated feature. System modules are strongly preferred over JMS resource definitions because specifying connection factories and destinations using a configurable system module is generally much more flexible, maintainable, and portable than hard coding configuration in an application.

  2. Create exactly one subdeployment per module. Subdeployments are sometimes referred to as "advanced targeting" on the WebLogic Server Administration Console. A single subdeployment aids simplicity - it is much easier for third parties to understand the targeting, and it reduces the chances of making configuration errors. If a single subdeployment is not sufficient, create two modules.
  3. Populate the subdeployment only with the JMS servers contained in the ‘homogenous set of JMS Servers` above (this will be a single JMS Server in a simplified cluster-targeted JMS configuration). Do not reference WebLogic Servers or a cluster in the subdeployment. Only include the JMS servers that you wish to host destinations. This ensures that when the JMS resources are configured in the next step below, they are targeted to the correct JMS servers. For modules that support non-distributed destinations, the subdeployment must only reference a single individually-configured JMS server, or a single cluster-targeted JMS server that references a store with its distribution-policy set to Singleton. For modules that support distributed destinations, always choose a single cluster-targeted JMS server with its distribution-policy set to Distributed, or a homogenous set of individually-configured JMS servers.
If you have a mix of distributed and non-distributed destinations, use two modules each with its own subdeployment.

Configure JMS Resources

Configure your JMS resources and target them properly.

  1. Create destinations and target them to a single subdeployment (called "advanced targeting" on the console). Do not use default targeting instead of a subdeployment. Note that only distributed destinations can be targeted to a subdeployment target that resolves to multiple JMS servers. If you have a mix of distributed destinations, stand alone destinations, and imported destinations, then use two modules each with its own subdeployment. See Targeting Best Practices.
  2. Create and use custom connection factories instead of using default connection factories. Default connection factories are not tunable.

    In most cases, you can use default targeting with connection factories as default targeting causes the resource to inherit the module's target. For connection factories that are only used by remote clients, use the module's subdeployment target.

  3. Set the connection factory unmapped resource reference mode to FailSafe instead of leaving it as its default value ReturnDefault. The value FailSafe ensures that applications do not use unmapped resource references. See Change in Behavior of Unmapped Connection Factory Resources in Release Notes for Oracle WebLogic Server.
    For more information about setting the unmapped resource reference mode, see Specifying the Unmapped Resource Reference Mode for Connection Factories.

Configure SAF Agents, Stores, and Imported Destination

SAF agents, their stores, and their imported destinations should follow the same best practices as JMS servers, their stores, and JMS destinations.

Targeting Best Practices

Oracle recommends certain targeting guidelines for JMS resources.

They are:

  • Avoid default targeting, WebLogic server targeting, and cluster targeting with destinations. Instead use advanced targeting (subdeployment targeting) for destinations and ensure that the subdeployment references only JMS servers or SAF agents. This applies to all destination types, including non-distributed, distributed, and imported.

    Even if the current JMS Servers or SAF Agents in your domain are only used for your specific application, this is a best practice because:

    • New JMS Servers or SAF Agents that are unrelated to your current application can be introduced by other applications, web services, or 3rd-party products.

    • In the future, your application may require different destinations and different JMS Servers or SAF Agents for scalability or management purposes.

  • Always use advanced targeting when configuring Web Services deployments and error queues, this includes both development and production environments.

  • To use an error destination within a distributed queue, it must be targeted to the same subdeployment as its parent destination.

  • In most cases, you can use default targeting with connection factories as default targeting causes the resource to inherit the module's target. For connection factories that are only used by remote clients, use the module's subdeployment target.

High Availability Best Practices

Learn some of the best practices to achieve and leverage high availability features in WebLogic Server.

This section includes the following topics:

Develop Applications on a Cluster

To achieve High Availability (HA), develop applications that leverage clustered WebLogic features and use a cluster during development. This approach is best taken in the early configuration and application design stage as it is a difficult process to change a non-clustered application into a clustered application.

Leverage WebLogic HA Features

In WebLogic JMS, a sent message is only available to consumers if the message’s host JMS server instance is running. Even if a message is stored on a shared file system or database, or in a distributed destination, the only JMS server instance that can recover a message is the same instance that originally stored the message. For example, if a message is sent to a distributed queue hosted on multiple JMS server instances, then the message will be internally load balanced to exactly one of these instances and stored in that particular instance, and, if that instance later crashes, the message will not be available to consumers until the instance is restarted.

To restore message availability after a failure, WebLogic includes features for automatically restarting and/or migrating an entire WebLogic Server JVM. It also includes features for restarting a JMS server and store instance within a JVM or migrating the instance to a different JVM within the same cluster after a failure. Finally, it includes features for clustering (distributing) a destination across multiple JMS servers within the same cluster. A distributed destination helps high availability because even if some of the destination’s stored messages are unavailable while they wait for their failed JMS server and store to restart or migrate, other messages for the logical destination can still be produced and consumed via a running JMS server.

HA is normally accomplished using a combination of:

  • WebLogic Clustering (Dynamic or Configured Clusters). See Understanding WebLogic Server Clustering in Administering Clusters for Oracle WebLogic Server.

  • Whole server migration and/or restart. See Whole Server Migration in Administering Clusters for Oracle WebLogic Server.

  • WebLogic JMS server and store Restart In Place. See Service Restart In Place in Administering the WebLogic Persistent Store.

  • JTA Service Migration between JVMs in a cluster (since JMS applications often leverage transactions). See Service Migration in Administering Clusters for Oracle WebLogic Server.

  • JMS Service Migration between JVMs in a cluster. See Service Migration in Administering Clusters for Oracle WebLogic Server.

  • Cluster leasing. Automatic service migration and automatic whole server migration both required setting up cluster leasing. It is a best practice to configure database leasing instead of cluster leasing. See Leasing in Administering Clusters for Oracle WebLogic Server.

  • Distributed destinations. See Using Distributed Destinations in Developing JMS Applications for Oracle WebLogic Server.

Ensure Your Data is Persisted Safely

  • If you are using file stores, ensure the files are located on highly available storage (such as RAID), and are centrally accessible from any machine in a cluster (via SAN, etc) or from any machine that might host a WebLogic Server after a whole server migration, so that file data can be recovered after a failure. Default file stores similarly also need to be highly available and centrally accessible if JTA is not using a JDBC TLog Store since transaction logs are stored in default file stores by default. See File Locations and Additional Requirement for High Availability File Stores in Administering the WebLogic Persistent Store.

    Note:

    It is important to explicitly configure the directory of a custom or default file store when ensuring the file store uses a central directory location. Otherwise, the file store may recover its data using a directory location based on the current WebLogic Server name, and so could recover from an incorrect directory if it moves between WebLogic Servers.

  • Note that paging and cache files do not need high availability and should be located on local file systems for performance reasons.

  • If you are using custom database stores, transaction log JDBC stores, or cluster database leasing, then ensure their database tables are located on a highly available database solution such as Oracle RAC.

  • If you have a Disaster Recovery solution that leverages async replication of data, then file base storage is not usually recommended. Instead, Oracle strongly recommends that all JMS and JTA data be stored on the same database as any applications that perform a combination of messaging and database operations. This ensures that your recovered messages and data stay synchronized even after a disaster recovery. See Using a JDBC Store and Using a JDBC TLog Store in Administering the WebLogic Persistent Store.

Client Resiliency Best Practices

Ensuring JMS resiliency generally requires attention in two main areas: infrastructure level resilience and JMS application resilience.

The first area is infrastructure level resilience, which is generally addressed via configuration and encompasses persistence, leveraging clusters, JVM Migration, and Service Migration as described above in High Availability Best Practices. The second area is JMS application resilience, which is generally addressed via coding best practices that apply to any JMS Provider (not just WebLogic JMS) and is described below.

On any unrecoverable client API level messaging failure with any JMS provider, it is the responsibility of the programmer to make sure that the related JMS resources are closed and recreated, and, if it’s desirable, that the failed operation be retried. The recommended steps for recreating a JMS resource mirror the steps for creating one. For example, if a JMS produce or JMS consume call throws an exception, close the parent JMS Connection or JMS Context, close the initial JNDI Context (if it is still open), and finally recreate the Initial Context, re-obtain the JMS Connection Factory and Destination from JNDI, and recreate the connection or JMSContext, session, and producer or consumer.

Exception handling in server-side applications is usually simplified by taking advantage of JMS asynchronous containers or pooling:

  • Error handling for synchronous applications in server side messaging can take advantage of built-in-pooling to handle the problem simply by, for example, creating a connection, session, and producer, and then closing the connection for each sent message. The pools will in turn retrieve objects from a cache or recreate them as needed. Pooling is activated transparently by using a resource reference to access a JMS connection factory, or JMS 2.0 Java EE 7 JMS Context injection. Note that even when objects are pooled via resource-reference, it is still usually a good idea to retrieve new JMS Connection Factory or Destination objects after an error (in case these objects have somehow changed). See Enhanced Support for Using WebLogic JMS with EJBs and Servlets in Developing JMS Applications for Oracle WebLogic Server.

  • Error handling for asynchronous ‘onMessage’ server side messaging is generally best handled by leveraging WebLogic MDB containers, or a JMS JCA Adapter from your framework if MDBs are not options. These containers will automatically handle failures and retry as needed. See Developing Message-Driven Beans for Oracle WebLogic Server for more information.

If an asynchronous messaging application cannot take advantage of a container, Oracle strongly recommends that the application register an ‘onException’ exception listener on their Connection to detect and handle failures. See the javadoc for javax.jms.Connection.setExceptionListener() or, if using JMS 2.0, see javax.jms.JMSContext.setExceptionListener().

Note:

  • There is one exception type that does not require recreating JMS client objects: a javax.jms.ResourceAllocationException thrown by a message producer. This exception indicates a message quota failure where the server is unable to accept a message because a quota condition has been reached.

  • Applications should avoid retrying operations in a tight loop in order to avoid performing relatively expensive create operations too frequently. This is because almost all failures do not resolve immediately, and frequently destroying and creating JMS client objects such as JNDI contexts, connections, sessions, producer, and consumers in the interim can be relatively far more expensive in comparison to normal runtime operations like sending or receiving a message. In short, tight-loop-retries can consume far more resources than other operations. Oracle recommends a single immediate retry attempt, and then progressively longer intervals between retries of up to a maximum of at least a few seconds.

  • It is a highly recommended best practice to pool or cache JMS resources. To simplify error handling, it is tempting to ignore this advice and write applications that always create a new JMS connection, session, etc for each JMS message. But if these items are not pooled or cached, then this approach is not recommended for the same costly reasons that are described above for a tight loop retry. Some messaging applications may see a 5X or more performance hit. If pooling is not available, Oracle recommends caching JMS objects in your application for re-use.

  • One can always assume an operation succeeded if it returns success, but one cannot always assume that an operation failed if it throws an exception. For example, a message send failure can occur even if the produced message successfully made it to the server destination, but the server was unable to send an internal success response back to the sender client. Another example is that a failed commit call does not necessarily indicate that the transaction did not commit (for similar reasons as the producer example).

  • The configurable WebLogic JMS Reconnect settings on JMS Connection Factories and the corresponding reconnection weblogic.jms.extension.WLConnection and weblogic.jms.extension.JMSContext APIs are deprecated. They do not handle all possible failures and so are not an effective substitute for the above resiliency best practices. They will be removed or ignored in a future release.

Distributed Destination Best Practices

Applications that use distributed destinations are more highly available than applications that use simple destinations because WebLogic JMS provides load balancing and failover for member destinations of a distributed destination within a cluster.

Distributed Queues

Distributed queues are fairly easy to apply to an arbitrary clustered queueing use case, and easiest to apply when using MDBs, the SOA JMS Adapter, or OSA Adapter to consume from them. The MDB and adapter options automatically ensure that all distributed destination members are serviced by consumers. In addition, these containers are resilient to failures, and generally provide a proven and simple way for securing and multi-threading consumer applications regardless of destination type.

Distributed Topics

Distributed Topics are best applied when you use MDBs, the SOA JMS adapter, or the OSA JMS adapter to subscribe since direct subscribers have limitations and may require use of sophisticated extensions. The MDB and adapter containers automatically setup subscriptions and consumers for you.

Distributed Topics are recommended to be setup up as “Partitioned Distributed Topics” (a type of Uniform Distributed Topic) instead of “Replicated Distributed Topics”. This is because PDTs tend to be more scalable and fully supported in all advanced features, while RDTs are not supported in a dynamic cluster, WebLogic Multi-Tenant, or cluster-targeted JMS configuration. A PDT is a Uniform Distributed Topic that has its forwarding-policy configured to be partitioned instead of replicated. If you are already using RDTs, consider replacing them with PDTs.

See Configuring and Deploying MDBs Using JMS Topics in Developing Message-Driven Beans for Oracle WebLogic Server, Using Distributed Destinations, and Replacing an RDT with a PDT in Developing JMS Applications for Oracle WebLogic Server.

Weighted Distributed Destinations

Oracle strongly recommends using Uniform Distributed Destinations in place of Weighted Distributed Destinations. Weighted Distributed Destinations are deprecated and were superseded by Uniform Distributed Destinations as of WebLogic Server 9.0. Weighted Distributed Destinations are not supported in dynamic cluster, WebLogic Multi-Tenant, or cluster-targeted-JMS configurations.

Understanding WebLogic JMS Client Options

For client applications that have a runtime environment independent of WebLogic Server, there are multiple JMS client options, including: Java, .NET, and C clients. See JMS Clients in Developing Stand-alone Clients for Oracle WebLogic Server.

Note:

WebLogic JMS clients do not directly support foreign transaction managers. Use the WebLogic TM if possible. For advanced users, the transaction subsystem Interposed Transaction Manager feature may be used as an XA resource. See Participating in Transactions Managed by a Third-Party Transaction Manager in Developing JTA Applications for Oracle WebLogic Server.

Understanding WebLogic URLs

Applications that are communicating with a remote WebLogic Server instance or cluster must specify a URL when creating their JNDI InitialContext objects and/or setting application attributes in order to connect to a server or a cluster.
  • Do not specify URLs for applications that run on the same server or cluster as their JMS resources. When an initial context is created without specifying URLs, it automatically references the local server or cluster JNDI.

  • If a URL resolves to multiple addresses, WebLogic Server clients will randomly select an address in the list to start with and then automatically try each address in turn until one succeeds.

  • In production systems, consider using DNS round robin or a hardware load balancer for initial hostname resolution rather than using the multiple host/port URL notation shown in URL syntax.

Note:

JMS connection factories are obtained from JNDI; however, by default, they load balance their connections independently of the JNDI context address. A JMS connection factory normally load balances across the servers included in the JMS connection factory's configured target. Similar to an EJB reference, a JMS connection factory is a 'smart stub' that contains a list of server addresses implicitly obtained from domain configuration and implicitly updated as a cluster grows and shrinks. This means that even if a JNDI context's URL only references a single server in a cluster, and a cluster-targeted or default targeted connection factory is obtained from this JNDI context, the JMS connections will still load balance across the entire cluster.

URL syntax

Learn about the WebLogic URL syntax and how it must be used to construct a URL for an application.

The WebLogic URL syntax is:

[t3|t3s|http|https|iiop|iiops]://address[,address]...

where

  • address = hostlist : portlist

  • hostlist = hostname [,hostname]...

  • portlist = portrange [+portrange]...

  • portrange = port [-port]

Use port-port to indicate a port range, and + to separate multiple port ranges. For example, a simple address is typically something like t3://hostA:7001; the address t3://hostA,hostB:7001-7002 is equivalent to the following addresses.

  • t3://hostA,hostB:7001+7002

  • t3://hostA:7001-7002,hostB:7001-7002

  • t3://hostA:7001+7002,hostB:7001+7002

  • t3://hostA:7001,hostA:7002,hostB:7001,hostB:7002

Strict Message Ordering Best Practices

Oracle recommends using the WebLogic JMS Unit-of-Order feature when strict message delivery ordering is required. UOO is the simplest and most capable strict delivery ordering option, and it supports parallel consumption of different orderings within the same destination. Normally it requires minimal or even no changes to applications, and it is resilient to any type of failure. In addition, it works with distributed destinations, scheduled messages, delayed messages, transactions, and store-and-forward.

Note that when using JMS Unit-of-Order in combination with a distributed destination or SAF imported destination, Oracle recommends configuring the destination’s unit-of-order routing policy to the Path Service option and configuring a Path Service for the cluster. The Path Service option preserves orderings even when new members are configured for the distributed destination, and is the only supported policy in a cluster-targeted JMS configuration.

See Using Message Unit-of-Order in Developing JMS Applications for Oracle WebLogic Server.

If strict messaging ordering is needed and the Unit-of-Order feature cannot be leveraged, see Ordered Redelivery of Messages in Developing JMS Applications for Oracle WebLogic Server.

Integrating Remote JMS Destinations

To integrate remote JMS destinations into a local WebLogic Server or WebLogic Cluster, it is a best practice to configure a Foreign JMS Server mapping in order to map remote JMS destination and connection factory JNDI names into the local standalone server JNDI or local cluster JNDI namespace. The destinations that can be mapped include remote WebLogic JMS destinations, Oracle AQ JMS destinations, and non-Oracle JMS destinations.

Furthermore, another best practice is to use Foreign JMS Server mappings in combination with MDBs, res-ref or context injection JMS pools, or Messaging Bridges. These components use the mapping plus any security credentials configured in the Foreign JMS Server to access remote JMS resources.

Alternatively, consider using WL JMS SAF agents to forward remote WebLogic JMS messages into a local server or cluster.

See FAQs: Integrating Remote JMS Providers in Developing JMS Applications for Oracle WebLogic Server.

JMS Performance and Tuning

The following link is for a checklist of items to consider when tuning WebLogic JMS:

JMS Security

For an overview of JMS security considerations for WebLogic Servers and clients, see Understanding JMS Security in Developing JMS Applications for Oracle WebLogic Server.