This section provides information about how to design messages to improve messaging performance:
The CPU cost of serializing Java objects can be significant. This expense, in turn, affects JMS Object messages. You can offset some of this cost by having application objects implement the
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 the
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 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 messages are serialized by the server.
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, then compression can actually increase its size. The JDK provides built-in compression libraries. For details, see the
For information about using JMS connection factories to specify the automatic compression of messages that exceed a specified threshold size, see Compressing Messages in the Tuning Performance of Oracle WebLogic Server.
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.
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.
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:
Ease of configuration.
Does not require a custom connection factory for asynchronous receivers, such as setting the
MessagingMaximum to 1 when using message-driven beans (MDBs).
Simple configuration when using distributed destinations.
Preserves message order during processing delays.
Preserves message order during transaction rollback or session recovery.
Oracle recommends applications that use Ordered Redelivery upgrade to Message Unit-of-Order. For more information, see Using the Message Unit-of-Order.
When you are start 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 use a Topic only if one of the following conditions applies:
The same message must be replicated to multiple consumers.
A message should be dropped if there are no active consumers that will select it.
There are many subscribers, each with a unique selector.
Note that a topic with a single durable subscriber is semantically similar to a queue. The differences are as follows:
If you change a topic selector for a durable subscriber, then all previous messages in the subscription are deleted, while if you change a queue selector for consumer, then no messages in the queue are deleted.
A queue may have multiple consumers, and will distribute its messages in a round-robin fashion, whereas a topic subscriber is limited to one consumer.
For more information about configuring JMS queues and topics, see Queue and Topic Destination Resources in Administering JMS Resources for Oracle WebLogic Server.
In general, asynchronous (
onMessage) consumers perform and scale better than synchronous consumers:
Asynchronous consumers create less network traffic. Messages are pushed unidirectionally, and are pipelined to the message listener. Pipelining supports the aggregation of multiple messages into a single network call.
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 Use Prefetch Mode to Create a Synchronous Message Pipeline.
Asynchronous consumers use fewer threads. An asynchronous consumer does not use a thread while it is inactive. A synchronous consumer consumes a thread for the duration of its receive call. As a result, a thread can remain idle for long periods, especially if the call specifies a blocking timeout.
For application code that runs on a server, it is almost always best to use asynchronous consumers, typically through MDBs. The use of asynchronous consumers prevents the application code from doing a blocking operation on the server. A blocking operation, in turn, idles a server-side thread; it can even cause deadlocks. Deadlocks occur when blocking operations consume all threads. When no threads remain to handle the operations required to unblock the blocking operation itself, that operation never stops blocking.
For more information, see Receiving Messages Asynchronously using the Classic API and Receiving Messages Synchronously Using the Classic API.
When designing an application, make sure you specify that messages will be sent in non persistent mode unless a persistent QOS is required. Oracle recommends non persistent mode because unless synchronous writes are disabled, a persistent QOS can cause a significant degradation in performance.
Avoid persisting sending persistent 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 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:
Producer's connection's connection factory configuration:
JMS Producer API override on QueueSender and TopicPublisher:
JMS Producer API per message override on QueueSender and TopicPublisher:
For queues, optional deliveryMode parameter on send()
For topics, optional deliveryMode parameter on publish()
Override on destination configuration:
No Delivery (default, implies no override)
Override on JMS server configuration:
If store is configured then that implies using the default persistent store that is available on each targeted WebLogic Server instance
If a Store is configured then that implies no override.
Non durable subscribers only:
If there are no subscribers, or there are only non durable subscribers for a topic, the messages will be downgraded to non persistent. (Because non durable subscribers exist only for the life of the JMS server, there is no reason for the message to persist.)
Because temporary destinations exist only for the lifetime of their host JMS server, there is no reason for messages to persist. WebLogic JMS automatically forces all messages in a temporary destination to non-persistent.
Durable subscribers require a persistent store to be configured on their JMS server, even if they receive only non persistent messages. A durable subscription persists to ensure that it continues through a server restart, as required by the JMS specification.
Because sending is generally faster than receiving , consider reducing the overhead associated with receiving by deferring acknowledgment of messages until several messages have been received and can be acknowledged collectively. If you are using transactions, then substitute the word
Deferment of acknowledgements is not likely to improve performance for non durable subscriptions, because of the 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—assuming that the wake-up message can be directed at the correct listener.
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 percent 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, Oracle recommends 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 provides alternative qualities of service (QOS) extensions that can help performance. This section contains the following topics:
Non durable topic subscribers can subscribe to messages using the
MULTICAST_NO_ACKNOWLEDGE. If a topic has such subscribers, then 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 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
acknowledge() have no effect on multicast messages.
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 has a higher QOS for non durable topic subscriptions by default than the JMS 1.1 specification requires.
A no-acknowledge delivery mode implies that the server gives messages to consumers, but does not expect an acknowledgement to be called. Instead, the server pre-acknowledges the message. In this acknowledge mode, calls to recover will not work, because the message was acknowledged. This mode saves the overhead of an additional network call to the acknowledge, at the expense of possibly losing a message when a server failure, a network failure, or a client failure occurs.
If an asynchronous client calls the
close() in this scenario, then all messages in the asynchronous pipeline are lost.
Asynchronous consumers that use a NO_ACKNOWLEDGE QOS may want to reduce their message pipeline size in order to lower the number of lost messages in the event of a failure.
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 the
close(). For this release, if WebLogic JMS determines that you created a multi threaded producer, then the server instance throws an exception
JMSException. If your application is thread limited, then try increasing the number of producers and sessions.
For WebLogic Server 9.0 and later, you can configure a JMS connection factory and destination to automatically propagate the message sender's authenticated username. The username is placed in a
javax.jms.Message property named
Consider the following points when using the
JMSXUserID property in your application.
While the JMS specification makes some mention of the
JMSXUserID property, the behavior is lightly defined and will likely be different for different JMS vendors.
JMSXUserID property is based on the credential of the thread an application uses to create the JMS producer. It does not derive from the credential that is on a thread during the JMS send call itself.
JMS will ignore or override any attempt by an application to directly set
JMSXUserID (for example,
javax.jms.Message.setXXXProperty() will not work).
JMS messages are not signed or encrypted (similar to any RMI/EJB call). Therefore, fully secure transfers of the
JMSXUserID require sending the message through secure protocols (for example,
WebLogic Store-and-Forward agents do not propagate the
JMSXUserID (they null it out).
WebLogic Messaging bridges will propagate
JMSXUserID property of the source destination's message if the messaging bridges are both are forwarding to a 9.0 or later JMS server and are configured to Preserve Message Properties. Otherwise, the forwarded message will either contain no username or the username used by the bridge sender. The latter behavior is determined by the configuration of the bridge sender's connection factory and destination.
The WebLogic JMS
WLMessageProducer.forward() extension can forward a received message's
JMSXUserID property interoperability behavior for WebLogic JMS clients prior to 9.0 is undetermined.
For instructions about setting the
JMSXUserID property on a connection factory or a destination, see the following topics in the WebLogic Server Administration Console online help:
For information about how to get the most out of your applications, implement the performance tuning features available with WebLogic JMS at Tuning WebLogic JMSin Tuning Performance of Oracle WebLogic Server.