Sun Java System Message Queue 3.5 SP1 Java Client Developer's Guide |
Chapter 4
Configuring the Message Queue Client RuntimeThe performance of client applications depends both on the inherent design of these applications and on the features and capabilities of the Message Queue client runtime.
This chapter describes how the Message Queue client runtime supports the messaging capabilities of client applications, with special emphasis on properties and behaviors that you can configure to improve performance and message throughput.
The chapter covers the following topics:
Message Production and ConsumptionThe Message Queue client runtime provides client applications with an interface to the Message Queue service—it supplies these clients with all the JMS programming objects introduced in The JMS Programming Model. It supports all operations needed for clients to send messages to destinations and to receive messages from such destinations.
This section provides a high level description of how the Message Queue client runtime supports message production and consumption. Figure 4-1 illustrates how message production and consumption involve an interaction between clients and the client runtime, while message delivery involves an interaction between the client runtime and the message server.
Figure 4-1 Messaging Operations
Once a client has created a connection to a broker, created a session as a single-threaded context for message delivery, and created the MessageProducer and MessageConsumer objects needed to access particular destinations in a message server, production (sending) and consumption (receiving) of messages can proceed.
Message Production
In message production, a message is created by the client, and sent over a connection to a destination on a broker. If the message delivery mode of the MessageProducer object has been set to persistent (guaranteed delivery, once and only once), the client thread blocks until the broker acknowledges that the message was delivered to its destination and stored in the broker’s persistent data store. If the message is not persistent, no broker acknowledgement message (referred to as “Ack” in property names) is returned by the broker, and the client thread does not block.
In the case of persistent messages, to increase throughput, you can set the connection to not require broker acknowledgement (see imqAckOnProduce property, Table 4-9), but this eliminates the guarantee that persistent messages are reliably delivered.
Message Consumption
Message consumption is more complex than production. Messages arriving at a destination on a broker are delivered over a connection to the client runtime under the following conditions:
Messages delivered over the connection are distributed to the appropriate sessions, where they are queued up to be consumed by the appropriate MessageConsumer objects, as shown in Figure 4-2.
Figure 4-2 Message Delivery to Message Queue Client Runtime
Note
The flow of messages delivered to the client runtime is metered at both the connection and consumer levels (see Message Flow Metering). By appropriately adjusting connection configuration properties, you can balance the flow of messages so that messages delivered to one session do not adversely affect the delivery of messages to other sessions on the same connection.
Messages are fetched off each session queue one at a time (a session is single threaded) and consumed either synchronously (by a client thread invoking the receive method) or asynchronously (by the session thread invoking the onMessage method of a MessageListener object).
When a broker delivers messages to the client runtime, it marks the messages accordingly, but does not really know if they have been consumed. Therefore, the broker waits for the client to acknowledge receipt of a message before deleting the message from the broker’s destination. If a connection fails, and another connection is subsequently established, the broker will re-deliver all previously delivered but unconsumed messages, marking them with a Redeliver flag.
In accordance with the JMS specification, there are three acknowledgment modes that you can specify for a client session:
- AUTO_ACKNOWLEDGE: the session automatically acknowledges each message consumed by the client.
- CLIENT_ACKNOWLEDGE: the client explicitly acknowledges after one or more messages have been consumed. This mode gives the client the most control. This acknowledgement takes place by invoking the acknowledge() method of a message object, causing the session to acknowledge all messages that have been consumed by the session since the previous invocation of the method. (This could include messages consumed asynchronously by many different message listeners in the session, independent of the order in which they were consumed.)
Note
Message Queue also provides a specific method you can use in CLIENT_ACKNOWLEDGE mode, by which you can acknowledge only the individual message on which you invoke the method, rather than the standard behavior. This is achieved using programming techniques described inCustom Client Acknowledgement.
- DUPS_OK_ACKNOWLEDGE: the session acknowledges after ten messages have been consumed (this value is not currently configurable) and doesn’t guarantee that messages are delivered and consumed only once. Clients use this mode if they don’t care if messages are processed more than once.
Each of the three acknowledgement modes requires a different level of processing and bandwidth overhead. AUTO_ACKNOWLEDGE consumes the most overhead and guarantees reliability on a message by message basis, while DUPS_OK_ACKNOWLEDGE consumes the least overhead, but allows for duplicate delivery of messages.
In the case of the AUTO_ACKNOWLEDGE or CLIENT_ACKNOWLEDGE modes, the threads performing the acknowledgement, or committing a transaction, will block, waiting for the broker to return a control message acknowledging receipt of the client acknowledgement. This broker acknowledgement (referred to as “Ack” in property names) guarantees that the broker has deleted the corresponding persistent message and will not send it twice—which could happen were the client or broker to fail, or the connection to fail, at the wrong time.
To increase throughput, you can set the connection to not require broker acknowledgement of client acknowledgements (see imqAckOnAcknowledge property, Table 4-7), but this eliminates the guarantee that persistent messages are delivered once and only once.
Client Runtime Configurable PropertiesThe Message Queue client runtime supports all the operations described in Message Production and Consumption. It also provides a number of configurable properties that you can use to optimize resources, performance, and message throughput. These properties correspond to attributes of the ConnectionFactory object used to create physical connections between a client runtime and a message server.
Note
If you wish to support distributed transactions (see Distributed Transactions), you need to use a special XAConnectionFactory object that supports distributed transactions.
A ConnectionFactory (or XAConnectionFactory) object has no physical representation in a broker—it is used simply to enable the client to establish connections with a broker and to specify behaviors of the connection and of the client runtime using the connection. (The ConnectionFactory object can also be used to manage Message Queue message server resources by overriding message header values set by clients—see Message Header Overrides.)
ConnectionFactory (and XAConnectionFactory) administered objects are created by adminstrators or instantiated in the application, as described in Chapter 3, "Using Administered Objects."
By configuring a ConnectionFactory (or XAConnectionFactory) administered object, you specify the attribute values (the properties) common to all the connections that it produces. ConnectionFactory and XAConnectionFactory objects share the same set of attributes. These attributes are grouped into a number of categories, depending on the behaviors they affect:
Each of these categories is discussed in the following sections with a description of the ConnectionFactory (or XAConnectionFactory) attributes each includes. The attribute values are set using Message Queue administration tools, as described in the Message Queue Administration Guide.
Connection Handling
Connections to a message server are specified by a broker host name, the port number at which the broker’s Port Mapper resides (or at which a specific connection service resides), and the kind of connection service used to access the broker (see the Message Queue Administration Guide for a discussion of the various connection services provided by Message Queue.)
This information is provided in a message server address that is used in connecting the client runtime to a broker. In the case of a multi-broker cluster, you might specify multiple message server addresses: if a broker or a connection fails, the connection can be automatically re-established with a different broker using a different message server address.
Specifying a Message Server Address
The syntax for specifying a message server address depends upon the connection service used to access a broker, as follows:
scheme://address_syntax
where the scheme and address_syntax are described in Table 4-1.
Table 4-1 Message Server Address Schemes and Syntax
Scheme
Connection Service
Description
Address Syntax
mq
jms
and
ssljmsMessage Queue client runtime makes a connection to the Message Queue Port Mapper at the specified host and port. The Port Mapper returns a list of the dynamically established connection service ports, and the client runtime then makes a connection to the port hosting the specified connection service.
[hostName][:port][/serviceName]
Defaults:1
hostName = localhost
port = 7676
serviceName = jmsmqtcp
jms
Message Queue client runtime makes a tcp connection to the specified host and port (bypassing the Message Queue Port Mapper) to establish a connection.
hostName:port/jms
mqssl
ssljms
Message Queue client runtime makes a secure ssl connection to the specified host and port (bypassing the Message Queue Port Mapper) to establish a connection.
hostName:port/ssljms
http
httpjms
Message Queue client runtime makes an HTTP connection to a Message Queue tunnel servlet at the specified URL. (The broker must be configured to access the HTTP tunnel servlet, as described in the Message Queue Administration Guide.)
http://hostName:port/
contextRoot/tunnel2https
httpsjms
Message Queue client runtime makes a secure HTTPS connection to the specified Message Queue tunnel servlet URL. (The broker must be configured to access the HTTPS tunnel servlet, as described in the Message Queue Administration Guide.)
https://hostName:port/
contextRoot/tunnel3
1Defaults only apply to the jms connection service. For the ssljms connection service, all variables need to be specified
2If multiple broker instances are using the same tunnel servlet, then the syntax for connecting to a specific broker instance (rather than a randomly selected one) is: http://hostName:port/contextRoot/tunnel?ServerName=hostName:instanceName
3If multiple broker instances are using the same tunnel servlet, then the syntax for connecting to a specific broker instance (rather than a randomly selected one) is: https://hostName:port/contextRoot/tunnel?ServerName=hostName:instanceName
To see how the message server address syntax applies in some typical cases, consult Table 4-2.
Connecting to a Message Server
Using a message server address provided by a ConnectionFactory (or XAConnectionFactory) attribute, a client runtime attempts to connect to the message server. If the message server address scheme involves the Message Queue Port Mapper (scheme = mq), then the Port Mapper dynamically assigns a port number and a connection is attempted to the specified port.
In some cases, you might wish to provide more than one message server address to which to make a connection. For example, in multi-broker cluster environments (Enterprise Edition only) when one broker might not be on line, you might wish to connect to another broker in the cluster. By specifying more than one address in the connection factory imqAddressList attribute, the system will automatically attempt a connection to a second address if a connection to the first address fails. The connection attempts continue until all addresses in a list are tried, after which the system recycles through the list a specified number of times, in attempting a connection.
Automatic Reconnect to a Message Server (Enterprise Edition)
Message Queue also provides an auto-reconnect capability, by which the client runtime can automatically reconnect to a broker if a connection fails. To enable this capability, you set the connection factory imqReconnectEnabled attribute.
While attempting to re-establish the connection, Message Queue maintains objects (sessions, message consumers, message producers, and so forth) provided by the client runtime. However, in circumstances where the client-side state cannot be fully restored on a broker upon reconnect (for example, when using transacted sessions or temporary destinations—which exist only for the duration of a connection), auto-reconnect will not take place, and the connection exception handler is called instead. (In such cases, application code has to catch the exception, reconnect, and restore state.)
A failed connection can be restored not only on the original broker, but also on a broker different from the original connection (that is, the reconnect is to the message server rather than to a specific broker instance within the message server cluster). To implement this behavior, you specify a list of message server addresses in the imqAddressList attribute.
When the client runtime needs to re-establish a connection to a message service, it will attempt a specified number of reconnect attempts (imqReconnectAttempts) to the original broker, each after a specified time interval (imqReconnectInterval). If these attempts fail, then the client runtime attempts to connect to other brokers in the list (the same number of times at the same time interval), until it finds an available broker or fails to find one. You can specify the number of times the client runtime iterates through the list in this way (imqAddressListIterations).
Because broker instances do not currently use a shared, highly available persistent store, persistent messages and other state information held by the failed (or disconnected) broker can be lost if a reconnect is to a broker instance different from the original. However, the ability of the client runtime to automatically reconnect to a different broker instance allows you to create recovery scenarios by which a backup broker or a broker cluster can be used for (less than complete) failover protection.
(If auto-reconnect is enabled, Message Queue persists temporary destinations when the associated connection fails, due to the possibility that clients might re-connect and access them again. After giving the client due time to reconnect and make use of these destinations, the broker will delete them.)
Auto-reconnect Behavior
The impact of auto-reconnect is different for message production and message consumption.
Message Production During reconnect, producers cannot send messages. The production of messages (or any operation that involves communication with the message server) is blocked until the connection is re-established.
Message Consumption Auto-reconnect is supported for all client acknowledgement modes. After a connection is re-established, the broker will redeliver all unacknowledged messages it had previously delivered, marking them with a Redeliver flag. JMS application code can use this flag to determine if any message has already been consumed (but not yet acknowledged). In the case of non-durable subscribers, some messages might be lost. This is because the message server does not hold messages for non-durable subscribers once their connections have been closed. Thus, any messages produced for these subscribers while the connection is down can not be delivered when the connection is re-established.
The attributes that affect connection handling are described in Table 4-3. (Connection handling attributes used in earlier, Message Queue 3.0 versions, which continue to be supported by Message Queue 3.5 SP1, are described in Message Queue 3.0 Connection Handling.)
Table 4-3 Connection Factory Attributes: Connection Handling
Attribute/Property Name
Description
imqAddressList
Specifies a list of message server addresses (one or more), separated by commas, each corresponding to a different broker instance to which a client runtime can connect. Each address in the list specifies the host name, host port, and connection service for the connection (see Specifying a Message Server Address).
Default: If no address is specified, this attribute defaults to an existing Message Queue 3.0 address (see Message Queue 3.0 Connection Handling), if any, or if not, to the first entry in Table 4-2.imqAddressListBehavior
Specifies whether connection attempts are in the order of addresses in the imqAddressList attribute (PRIORITY) or in a random order (RANDOM). If you have many clients attempting a connection using the same connection factory, you would use a random order to prevent them from all being connected to the same address.
Default: PRIORITYimqAddressListIterations
Specifies the number of times the client runtime will iterate through the imqAddressList in an effort to establish (or re-establish a connection). A value of -1 indicates that the number of attempts is unlimited.
Default: 5imqReconnectEnabled
If enabled (value = true), specifies that the client runtime will attempt to reconnect to a message server (or the list of addresses in imqAddressList) when a connection is lost.
Default: falseimqReconnectAttempts
Specifies the number of attempts to connect (or reconnect) for each address in the imqAddressList before the client runtime moves on to try the next address in the list. A value of -1 indicates that the number of reconnect attempts is unlimited (the client runtime will attempt to connect to the first address until it succeeds).
Default: 0imqReconnectInterval
Specifies the interval between reconnect attempts. this applies for attempts on each address in the imqAddressList and for successive addresses in the list. If too short, this time interval does not give a broker time to recover. If too long, the reconnect might represent an unacceptable delay.
Default: 3000 milliseconds
Message Queue 3.0 Connection Handling
Connection handling attributes used in earlier, Message Queue 3.0 versions continue to be supported by Message Queue 3.5 SP1, for purposes of compatibility. These attributes are shown in Table 4-4.
The Message Queue 3.0 attributes should not be used. They correspond to a different connection handling approach that does not support multiple message server addresses for establishing a connection.
If an address is specified in the imqAddressList attribute (see Table 4-3), then any existing Message Queue 3.0 connection handling attributes will be ignored.
Client Identification
Clients need to be identified to a broker both for authentication purposes and to keep track of durable subscriptions (see Client Identifiers).
For authentication purposes, Message Queue provides a default user name and password. These are a convenience for developers who do not wish to explicitly populate a user repository (see the Message Queue Administration Guide) to perform application testing.
To keep track of durable subscriptions, Message Queue uses a unique client identification (ClientID). If a durable subscriber is inactive at the time that messages are delivered to a topic destination, the broker retains messages for that subscriber and delivers them when the subscriber once again becomes active. The only way for the broker to identify the subscriber is through its ClientID.
There are a number of ways that the ClientID can be set for a connection. For example, application code can use the setClientID() method of a Connection object. The ClientID must be set before using the connection in any way; once the connection is used, the ClientID cannot be set or reset.
Setting the ClientID in application code, however, is not optimal. Each user needs a unique identification: this implies some centralized coordination. Message Queue therefore provides a imqConfiguredClientID attribute on the ConnectionFactory object. This attribute can be used to provide a unique ClientID to each user. To use this feature, the value of imqConfiguredClientID is set as follows:
imqConfiguredClientID=${u}string
where the special reserved characters, ${u}, provide a unique user identification during the user authentication stage of establishing a connection, and string is a text value unique to the ConnectionFactory object. When used properly, the message server will substitute u:userName for the u, resulting in a user-specific ClientID.
The ${u} must be the first four characters of the attribute value. If anything other than “u” is encountered, it will result in an JMS exception upon connection creation. When ${} is used anywhere else in the attribute value, it is treated as plain text and no variable substitution is performed.
An additional attribute, imqDisableSetClientID, can be set to true to disallow clients that use the connection factory from changing the configured ClientID through the setClientID() method of the Connection object.
It is required that you set the client identifier whenever using durable subscriptions in deployed applications, either programmatically using the setClientID() method or using the imqConfiguredClientID attribute of the ConnectionFactory object.
The attributes that affect client identification are described in Table 4-5.
Message Header Overrides
A Message Queue administrator can override JMS message header fields that specify the persistence, lifetime, and priority of messages. Specifically, values in the following fields can be overridden (see The Java XML Messaging (JAXM) Specification):
The ability to override message header values gives an administrator more control over the resources of a message server. Overriding these fields, however, has the risk of interfering with application-specific requirements (for example, message persistence). So this capability should only be used in consultation with the appropriate application users or designers.
Message Queue allows message header overrides at the level of a connection: overrides apply to all messages produced in the context of a given connection, and are configured by setting attributes of the corresponding connection factory administered object. These attributes are described in Table 4-6.
Reliability And Flow Control
A number of attributes determine the use and flow of Message Queue control messages by the client runtime, especially broker acknowledgements (referred to as “Ack” in the attribute names).
The attributes that affect reliability and flow control are described in Table 4-7. For an extended discussion of these settings and the effect of various permutations, see Managing Reliability and Performance.
Table 4-7 Connection Factory Attributes: Reliability and Flow Control
Attribute/Property Name
Description
imqAckTimeout
Specifies the maximum time in milliseconds that the client runtime will wait for any broker acknowledgement before throwing an exception. A value of 0 means there is no time-out—the client runtime will wait forever. Default: 0
In some situations, for example, the first time a broker authenticates a user against an LDAP user repository over a secure (SSL) connection, it can take upwards of 30 seconds to complete authentication. If imqAckTimeout is set too small, the client runtime can time out.
imqAckOnProduce
Specifies broker acknowledgement of messages from producing client:
If set to true, the broker acknowledges receipt of all JMS messages (persistent and non-persistent) from producing client, and producing client thread will block waiting for those acknowledgements (referred to as “Ack” in property name).
If set to false, broker does not acknowledge receipt of any JMS message (persistent or non-persistent) from producing client, and producing client thread will not block waiting for broker acknowledgements.
If not specified, broker acknowledges receipt of persistent messages only, and producing client thread will block waiting for those acknowledgements.
Default: not specified
imqAckOnAcknowledge
Specifies broker response to a consuming client when the client acknowledges a consumed message:
If set to true, broker acknowledges all consuming client acknowledgements, and consuming client thread will block waiting for such broker acknowledgements (referred to as “Ack” in property name).
If set to false, broker does not acknowledge any consuming client acknowledgements, and consuming client thread will not block waiting for such broker acknowledgements.
If not specified, broker acknowledges consuming client acknowledgements for AUTO_ACKNOWLEDGE and CLIENT_ACKNOWLEDGE mode (and consuming client thread will block waiting for such broker acknowledgements), but does not acknowledge consuming client acknowledgements for DUPES_OK_ACKNOWLEDGE mode (and consuming client thread will not block.)
Default: not specified
imqConnectionFlowCount
Specifies the number of JMS messages in a metered batch. When this number of JMS messages is delivered to the client runtime, delivery is temporarily suspended, allowing any control messages that had been held up to be delivered. Payload message delivery is resumed upon notification by the client runtime, and continues until the count is again reached.
If the count is set to 0 then there is no restriction in the number of JMS messages in a metered batch. A non-zero setting allows the client runtime to meter message flow so that Message Queue control messages are not blocked by heavy JMS message delivery.
Default: 100imqConnectionFlowLimit
EnabledIf enabled (value = true), the value of imqConnectionFlowLimit is used to limit message flow at the connection level.
Default: false
imqConnectionFlowLimit
Specifies a limit on the number of messages that can be delivered over a connection and buffered in the client runtime, waiting to be consumed. Note however, that unless imqConnectionFlowIsLimited is enabled, this limit is not checked.
When the number of JMS messages delivered to the client runtime (in accordance with the flow metering governed by imqConnectionFlowCount) exceeds this limit, message delivery stops. It is resumed only when the number of unconsumed messages drops below the value set with this property.
This limit prevents a consuming client that is taking a long time to process messages from being overwhelmed with pending messages that might cause it to run out of memory.
Default: 1000
imqConsumerFlowLimit
Specifies a limit on the number of messages per consumer that can be delivered over a connection and buffered in the client runtime, waiting to be consumed. This limit is used to improve load-balancing among consumers in multi-consumer queue delivery situations (no one consumer can be sent a disproportionate number of messages). This limit can be overridden by a lower value set on the broker side for the queue’s consumerFlowLimit attribute (see information on destination attributes in the Message Queue Administration Guide).
This limit also helps prevent any one consumer on a connection from starving other consumers on the connection.
When the number of JMS messages delivered to the client runtime exceeds this limit for any consumer, message delivery for that consumer stops. It is resumed only when the number of unconsumed messages for that consumer drops below the value set with imqConsumerFlowThreshold.
(Note that if the total number of messages buffered for all consumers on a connection exceeds the imqConnectionFlowLimit, then delivery of messages through the connection will stop until that total drops below the connection limit.)
Default: 100
imqConsumerFlow
ThresholdSpecifies, as a percentage of imqConsumerFlowLimit, the number of messages per consumer buffered in the client runtime, below which delivery of messages for a consumer will resume. For more information, see Message Flow Limits.
Default: 50
Queue Browser Behavior and Server Session
The attributes that affect queue browsing for the client runtime are described in Table 4-8.
JMS-Defined Properties Support
JMS-defined properties are property names reserved by JMS, and which a JMS provider can choose to support (see The Java XML Messaging (JAXM) Specification). These properties enhance client programming capabilities.
The JMS-defined properties supported by Message Queue are described in Table 4-9.
Managing Reliability and PerformanceBecause of the mechanisms by which messages are delivered to and from a broker, and because of the Message Queue control messages used to assure reliable delivery, there are a number of factors that affect reliability and performance. Some of these factors depend on messaging application design (delivery mode and acknowledgement mode) and some depend on client runtime behaviors (message flow metering and message flow limits).
Although these factors are quite distinct, their interactions can complicate the task of balancing reliability with performance. Specifically, because JMS messages and Message Queue control messages flow across the same connection between the client and the broker, you need to understand how to balance the requirement for reliability with the need for throughput.
This section describes the factors that affect reliability and performance, and the connection factory attributes that help manage message flow.
Delivery Mode
The delivery mode specifies whether a message is to be delivered at most once (non-persistent) or once and only once (persistent). These different reliability requirements imply different degrees of overhead. Specifically, the management of persistent messages requires greater use of broker control messages flowing across a connection.
Client Acknowledgement Mode
The setting of the client acknowledgement mode impacts reliability and affects the number of client and broker acknowledgement messages passing over a connection:
If this mode, with a synchronous receiver, it is possible for a message to be partially processed, but lost, if the system fails before the message is consumed. For increased reliability, you can use the CLIENT_ACKNOWLEDGE mode or a transacted session to guarantee no message is lost if the system fails.
- In the CLIENT_ACKNOWLEDGE mode client acknowledgements and broker acknowledgements are batched (rather than being sent one by one). This conserves connection bandwidth and generally reduces the overhead for broker acknowledgements, as compared to the AUTO_ACKNOWLEDGE mode. Of course, if in this mode, the client acknowledges each message, no batching will occur, and the acknowledgements are sent one by one.
- In the DUPS_OK_ACKNOWLEDGE mode, throughput is improved even further, because client acknowledgements are batched and because the client thread does not block (broker acknowledgements are not requested). However, in this case, the same message can be delivered and consumed more than once.
Message Flow Metering
Messages sent and received by clients (JMS messages) and Message Queue control messages pass over the same client-broker connection. Because of this, delays may occur in the delivery of control messages, such as broker acknowledgements, if these are held up by the delivery of JMS messages. To prevent this type of congestion, Message Queue meters the flow of JMS messages across a connection.
JMS messages are batched (as specified with the imqConnectionFlowCount property) so that only a set number are delivered; when the batch has been delivered, delivery of JMS messages is suspended, and pending control messages are delivered. This cycle repeats, as other batches of JMS messages are delivered, followed by queued up control messages.
The value of imqConnectionFlowCount should be kept low if the client is doing operations that require many responses from the broker; for example, the client is using the CLIENT_ACKNOWLEDGE or AUTO_ACKNOWLEDGE modes, persistent messages, transactions, queue browsers, or if the client is adding or removing consumers. If, on the other hand, the client has only simple consumers on a connection using DUPS_OK mode, you can increase imqConnectionFlowCount without compromising performance.
Message Flow Limits
There is a limit to the number of JMS messages that the Message Queue client runtime can handle before encountering local resource limitations, such as memory. When this limit is approached, performance suffers. Hence, Message Queue lets you limit the number of messages per consumer that can be delivered over a connection (imqConsumerFlowLimit) and buffered in the client runtime, waiting to be consumed.
When the number of JMS messages delivered to the client runtime exceeds this limit (imqConsumerFlowLimit) for any consumer, message delivery for that consumer stops. It is resumed only when the number of unconsumed messages for that consumer drops below the value set with imqConsumerFlowThreshold. The following example illustrates the use of these limits: consider the default settings for topic consumers
imqConsumerFlowLimit=1000
imqConsumerFlowThreshold=50
When the consumer is created, the broker delivers the initial batch of 1000 messages (providing they exist) to this consumer without pausing. After sending 1000 messages, the broker stops delivery until the client runtime asks for more messages. The client runtime holds these messages until the application processes them. The client runtime then allows the application to consume at least 50% (imqConsumerFlowThreshold) of the message buffer capacity (i.e. 500 messages) before asking the broker to send the next batch.
In the same situation, if the threshold were 10%, the client runtime would wait for the application to consume at least 900 messages before asking for the next batch. The next batch size is calculated as follows:
imqConsumerFlowLimit - (current # of pending msgs in buffer)
So, if imqConsumerFlowThreshold is 50%, the next batch size can fluctuate between 500 and 1000, depending on how fast the application can process the messages. Thus, the protocol guarantees two things:
If the imqConsumerFlowThreshold is too high (close to 100%), the broker will tend to send smaller batches, which can lower message throughput. If the value is too low (close to 0%), the broker might be able to finish the remaining buffered messages before the broker delivers the next set. This can also cause message throughput degradation. Thus, for most applications, it only makes sense to tune the imqConsumerFlowLimit value because it controls memory requirements. Unless you have specific performance or reliability concerns, there is no need to fine tune the imqConsumerFlowThreshold attribute.
These consumer-based flow controls are the best way to manage memory in the client runtime. Generally, depending on the client application, you know the number of consumers you need to support on any connection, the size of the messages, and the total amount of memory that is available to the client runtime.
In the case of some client applications, however, the number of consumers might be indeterminate, depending on choices made by end users. In those cases, you can still manage memory, using connection-level flow limits.
Connection-level flow controls limit the total number of messages buffered for all consumers on a connection. If this number exceeds the imqConnectionFlowLimit, then delivery of messages through the connection will stop until that total drops below the connection limit. (The imqConnectionFlowLimit is only enabled if you set the imqConnectionFlowLimitEnabled property to true.)
The number of messages queued up in a session is a function of the number of message consumers using the session and the message load for each consumer. If a client is exhibiting delays in producing or consuming messages, you can normally improve performance by redesigning the application to distribute message producers and consumers among a larger number of sessions or to distribute sessions among a larger number of connections.