Aside from the reliability your client requires, the design decisions that relate to producers and consumers include the following:
Do you want to use a point-to-point or a publish/subscribe domain?
There are some interesting permutations here. There are times when you would want to use publish/subscribe even when you have only one subscriber. On the other hand, performance considerations might make the point-to-point model more efficient than the publish/subscribe model, when the work of sorting messages between subscribers is too costly. Sometimes You cannot make these decisions cannot in the abstract, but must actually develop and test different prototypes.
Are you using an asynchronous message consumer that does not receive messages often or a producer that is seldom used?
Let the administrator know how to set the ping interval, so that your client gets an exception if the connection should fail. For more information see Using the Client Runtime Ping Feature.
Are you using a synchronous consumer in a distributed application?
You might need to allow a small time interval between connecting and calling the receiveNoWait() method in order not to miss a pending message. For more information, see Synchronous Consumption in Distributed Applications.
Do you need message compression?
Benefits vary with the size and format of messages, the number of consumers, network bandwidth, and CPU performance; and benefits are not guaranteed. For a more detailed discussion, see Message Compression.
A connection can have a client identifier. This identifier is used to associate a JMS client’s connection to a message service, with state information maintained by the message service for that client. The JMS provider must ensure that a client identifier is unique, and applies to only one connection at a time. Currently, client identifiers are used to maintain state for durable subscribers. In defining a client identifier, you can use a special variable substitution syntax that allows multiple connections to be created from a single ConnectionFactory object using different user name parameters to generate unique client identifiers. These connections can be used by multiple durable subscribers without naming conflicts or lack of security.
Message Queue allows client identifiers to be set in one of two ways:
Programmatically: You use the setClientID method of the Connection object. If you use this method, you must set the client id before you use the connection. Once the connection is used, the client identifier cannot be set or reset.
Administratively: The administrator specifies the client ID when creating the connection factory administrative object. See Client Identifier in Sun Java System Message Queue 4.3 Administration Guide.
In general, all messages sent to a destination by a single session are guaranteed to be delivered to a consumer in the order they were sent. However, if they are assigned different priorities, a messaging system will attempt to deliver higher priority messages first.
Beyond this, the ordering of messages consumed by a client can have only a rough relationship to the order in which they were produced. This is because the delivery of messages to a number of destinations and the delivery from those destinations can depend on a number of issues that affect timing, such as the order in which the messages are sent, the sessions from which they are sent, whether the messages are persistent, the lifetime of the messages, the priority of the messages, the message delivery policy of queue destinations (see Chapter 17, Physical Destination Property Reference, in Sun Java System Message Queue 4.3 Administration Guide), and message service availability.
The use of selectors can have a significant impact on the performance of your application. It’s difficult to put an exact cost on the expense of using selectors since it varies with the complexity of the selector expression, but the more you can do to eliminate or simplify selectors the better.
One way to eliminate (or simplify) selectors is to use multiple destinations to sort messages. This has the additional benefit of spreading the message load over more than one producer, which can improve the scalability of your application. For those cases when it is not possible to do that, here are some techniques that you can use to improve the performance of your application when using selectors:
Have consumers share selectors. As of version 3.5 of Message Queue, message consumers with identical selectors “share” that selector in imqbrokerd which can significantly improve performance. So if there is a way to structure your application to have some selector sharing, consider doing so.
Use IN instead of multiple string comparisons. For example, the following expression:
color IN (’red’, ’green’, ’white’)
is much more efficient than this expression
color = ’red’ OR color = ’green’ OR color = ’white’
especially if the above expression usually evaluates to false.
Use BETWEEN instead of multiple integer comparisons. For example:
size BETWEEN 6 AND 10
is generally more efficient than
size >= 6 AND size <= 10
especially if the above expression usually evaluates to true.
Order the selector expression so that Message Queue can determine its evaluation as soon as possible. (Evaluation proceeds from left to right.) This can easily double or triple performance when using selectors, depending on the complexity of the expression.
If you have two expressions joined by an OR, put the expression that is most likely to evaluate to TRUE first.
If you have two expressions joined by an AND, put the expression that is most likely to evaluate to FALSE first.
For example, if size is usually greater than 6, but color is rarely red you’d want the order of an OR expression to be:
size > 6 OR color = ’red’
If you are using AND:
color = ’red’ AND size > 6