Skip Headers
Oracle® Fusion Middleware Programming JMS for Oracle WebLogic Server
12c Release 1 (12.1.1)

Part Number E24387-03
Go to Documentation Home
Home
Go to Table of Contents
Contents
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
PDF · Mobi · ePub

3 Best Practices for Application Design

This chapter describes design options for WebLogic Server JMS, application behaviors to consider during the design process, and recommended design patterns.

Message Design

This section provides information on how to design messages improve messaging performance:

Serializing Application Objects

The CPU cost of serializing Java objects can be significant. This expense, in turn, affects JMS Object messages. You can offset this cost, to some extent, by having application objects implement java.io.Externalizable, but there still will be significant overhead in marshalling the class descriptor. To avoid the cost of having to write the class descriptors of additional objects embedded in an Object message, have these objects implement Externalizable, and call readExternal and writeExternal on them directly. For example, call obj.writeExternal(stream) rather than stream.writeObject(obj). Using Bytes and Stream messages is generally a preferred practice.

Serializing strings

Serializing Java strings is more expensive than serializing other Java primitive types. Strings are also memory intensive, they consume two bytes of memory per Character, and cannot compactly represent binary data (integers, for example). In addition, the introduction of string-based messages often implies an expensive parse step in the application in order to process the String into something the application can make direct use of. Bytes, Stream, Map and even Object messages are therefore sometimes preferable to Text and XML messages. Similarly, it is preferable to avoid the use of strings in message properties, especially if they are large.

Server-side serialization

WebLogic JMS servers do not incur the cost of serializing non-persistent messages. Serialization of non-persistent message types is incurred by the remote client. Persistent are serialized by the server.

Selection

Using a selector is expensive. This consideration is important when you are deciding where in the message to store application data that is accessed via JMS selectors.

Message Compression

Compressing large messages in a JMS application can improve performance. This reduces the amount of time required to transfer messages across the network, reduces the amount of memory used by the JMS server, and, if the messages are persistent, reduces the size of persistent writes. Text and XML messages can often be compressed significantly. Of course, compression is achieved at the expense of an increase in the CPU usage of the client.

Keep in mind that the benefits of compression become questionable for smaller messages. If a message is less than a few KB in size, compression can actually increase its size. The JDK provides built-in compression libraries. For details, see the java.util.zip package.

For information on using JMS connection factories to specify the automatic compression of messages that exceed a specified threshold size, see "Compressing Messages" in the Performance and Tuning for Oracle WebLogic Server.

Message Properties and Message Header Fields

Instead of user-defined message properties, consider using standard JMS message header fields or the message body for message data. Message properties incur an extra cost in serialization, and are more expensive to access than standard JMS message header fields.

Also, avoid embedding large amounts of data in the properties field or the header fields; only message bodies are paged out when paging is enabled. Consequently, if user-defined message properties are defined in an application, avoid the use of large string properties.

For more information, see Message Header Fields and Message Property Fields.

Message Ordering

You should use the Message Unit-of-Order feature rather than Ordered Redelivery to guarantee ordered message processing. The advantages of Message Unit-of-Order over Ordered Redelivery are:

Oracle recommends applications that use Ordered Redelivery upgrade to Message Unit-of-Order. For more information, see Chapter 10, "Using Message Unit-of-Order."

Topics vs. Queues

Surprisingly, when you are starting to design your application, it is not always immediately obvious whether it would be better to use a Topic or Queue. In general, you should choose a Topic only if one of the following conditions applies:

It is interesting to note that a topic with a single durable subscriber is semantically similar to a queue. The differences are as follows:

For more information on configuring JMS queues and topics, see "Queue and Topic Destination Resources" in Configuring and Managing JMS for Oracle WebLogic Server.

Asynchronous vs. Synchronous Consumers

In general, asynchronous (onMessage) consumers perform and scale better than synchronous consumers:

For more information, see Receiving Messages Asynchronously and Receiving Messages Synchronously.

Persistent vs. Non-Persistent Messages

When designing an application, make sure you specify that messages will be sent in non-persistent mode unless a persistent QOS is required. We recommend non-persistent mode because unless synchronous writes are disabled, a persistent QOS almost certainly causes a significant degradation in performance.

Note:

Take special care to avoid persisting messages unintentionally. Occasionally an application sends persistent messages even though the designer intended the messages to be sent in non persistent mode.

If your messages are truly non-persistent, none should end up in a regular JMS store. To make sure that none of your messages are unintentionally persistent, check whether the JMS store size grows when unconsumed messages are accumulating on the JMS server. Here is how message persistence is determined, in order of precedence:

Durable subscribers require a persistent store to be configured on their JMS server, even if they receive only non-persistent messages. A durable subscription is persisted to ensure that it continues through a server restart, as required by the JMS specification.

Deferring Acknowledges and Commits

Because sends are generally faster than receives, consider reducing the overhead associated with receives by deferring acknowledgment of messages until several messages have been received and can be acknowledged collectively. If you are using transactions substitute the word commit for acknowledge.

Deferment of acknowledgements is not likely to improve performance for non-durable subscriptions, however, because of internal optimizations already in place.

It may not be possible to implement deferred acknowledgements for asynchronous listeners. If an asynchronous listener acknowledges only every 10 messages, but for some reason receives only 5, then the last few messages may not be acknowledged. One possible solution is to have the asynchronous consumer post synchronous, non-blocking receives from within its onMessage() callback to receive subsequent messages. Another possible solution is to have the listener start a timer that, when triggered, sends a message to the listener's destination in order to wake it up and complete the outstanding work that has not yet been acknowledged—provided the wake-up message can be directed solely at the correct listener.

Using AUTO_ACK for Non-Durable Subscribers

Non-durable, non-transactional topic subscribers are optimized to store local copies of the message on the client side, thus reducing network overhead when acknowledgements are being issued. This optimization yields a 10-20% performance improvement, where the improvement is more evident under higher subscriber loads.

One side effect of this optimization, particularly for high numbers of concurrent topic subscribers, is the overhead of client-side garbage collection, which can degrade performance for message subscriptions. To prevent such degradation, we recommended allocating a larger heap size on the subscriber client. For example, in a test of 100 concurrent subscribers running in 10 JVMs, it was found that giving clients an initial and maximum heap size of 64MB for each JVM was sufficient.

Alternative Qualities of Service, Multicast and No-Acknowledge

WebLogic JMS provides alternative qualities of service (QOS) extensions that can aid performance.

Using MULTICAST_NO_ACKNOWLEDGE

Non-durable topic subscribers can subscribe to messages using MULTICAST_NO_ACKNOWLEDGE. If a topic has such subscribers, the JMS server will broadcast messages to them using multicast mode. Multicast improves performance considerably and provides linear scalability, as the network only needs to handle only one message, regardless of the number of subscribers, rather than one message per subscriber. Multicast messages may be lost if the network is congested, or if the client falls behind in processing them. Calls to recover() or acknowledge() have no effect on multicast messages.

Note:

On the client side, each multicasting session requires a dedicated thread to retrieve messages off the multicast socket. Therefore, you should increase the JMS client-side thread pool size to adjust for this.

This QOS extension has the same level of guarantee as some JMS implementations default QOS from vendors other than Oracle WebLogic Server for non-durable topic subscriptions. The JMS 1.1 specification specifically allows non-durable topic messages to be dropped (deleted) if the subscriber is not ready for them. WebLogic JMS actually has a higher QOS for non-durable topic subscriptions by default than the JMS 1.1 specification requires.

Using NO_ACKNOWLEDGE

A no-acknowledge delivery mode implies that the server gives messages to consumers, but does not expect acknowledge to be called. Instead, the server pre-acknowledges the message. In this acknowledge mode, calls to recover will not work, as the message is already acknowledged. This mode saves the overhead of an additional network call to acknowledge, at the expense of possibly losing a message when a server failure, a network failure, or a client failure occurs.

Note:

If an asynchronous client calls close() in this scenario, all messages in the asynchronous pipeline are lost.

Asynchronous consumers that use a NO_ACKNOWLEDGE QOS may wish to tune down their message pipeline size in order to reduce the number of lost messages in the event of a crash.

Avoid Multi-threading

The JMS Specification, at http://www.oracle.com/technetwork/java/jms/index.html, states that multi-threading a session, producer, consumer, or message method results in undefined behavior except when calling close(). For this release, if WebLogic JMS determines that you created a multi-threaded producer, the server instance throws a JMSException. If your application is thread limited, try increasing the number of producers and sessions.

Using the JMSXUserID Property

For WebLogic Server 9.0 and later, you can configure a JMS connection factory and/or destination to automatically propagate the message sender's authenticated username. The username is placed in a javax.jms.Message property named JMSXUserID.

Consider the following points when using the JMSXUserID property in your application.

For instructions on setting the JMSXUserID property on a connection factory or destination, see the following topics in the Administration Console online help:

Performance and Tuning

For information on how to get the most out of your applications, implement the performance tuning features available with WebLogic JMS at "Tuning WebLogic JMS" in Performance and Tuning for Oracle WebLogic Server.