These sections discuss design options for WebLogic Server JMS, application behaviors to consider during the design process, and recommended design patterns.
This section provides information on how to design messages improve messaging performance:
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
writeExternal on them directly. For example, call
obj.writeExternal(stream) rather than
Stream messages is generally a preferred practice.
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.
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.
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.
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, seein the WebLogic Performance and Tuning Guide.
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.
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:
BEA recommends applications that use Ordered Redelivery upgrade to Message Unit-of-Order. For more information, see Using Message Unit-of-Order.
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, seein Configuring and Managing WebLogic JMS.
In general, asynchronous (onMessage) consumers perform and scale better than synchronous consumers:
|Note:||In WebLogic Server, your synchronous consumers can also use the same efficient behavior as asynchronous consumers by enabling the Prefetch Mode for Synchronous Consumers option on JMS connection factories, as described in Using the Prefetch Mode to Create a Synchronous Message Pipeline.|
For more information, see Receiving Messages Asynchronouslyand Receiving Messages Synchronously
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.
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.
In WebLogic Server 7.0 and higher, 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.
WebLogic JMS 6.0 and above provide alternative qualities of service (QOS) extensions that can aid performance.
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 BEA WebLogic Server for non-durable topic subscriptions. The JMS 1.0.2 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.0.2 specification requires.
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
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.
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.