IBM® MQ Services for Kaazing Gateway
This document describes the new IBM® MQ Service for the Gateway, named ibmmq
, that enables Kaazing JMS clients to integrate with IBM® MQ messaging middleware.
The ibmmq
service is a special variant of the standard jms
service designed to be used with IBM® MQ. The general functionality of ibmmq
is described in this document, but to understand all of the features and configuration options available to ibmmq
as a variant of jms
, you should read the documentation for the jms
service, in JMS Services for Kaazing Gateway.
Note: For configuration information, see Integrate IBM® MQ Service.
- Overview
- IBM® MQ Service Specific Properties
- Individual Message Acknowledgment
- Queue Message Distribution to All Consumers
- JNDI Context
- Property Based Routing (PBR) with MQ
Overview
Kaazing WebSocket Gateway provides features and performance optimizations for IBM® MQ by using a new variant of the jms
service with service type ibmmq
. The ibmmq
service is configured like the jms
service, but ibmmq
also provides a simpler option which does not require use of an initial context to connect to IBM® MQ. Here is an example:
<service> <name>IBM MQ JMS Service</name> <description>Optimized JMS Service for IBM MQ</description> <accept>wss://example.com:443/jms</accept> <type>ibmmq</type> <properties> <queue.manager>QM1</queue.manager> <server.channel>SYSTEM.DEF.SVRCONN</server.channel> <host>mq.acme.com</host> <port>1414</port> <!-- other properties, as on the jms service, for example: --> <queue.maximum.pending.acknowledgments>10</queue.maximum.pending.acknowledgments> </properties> </service>
You can directly specify the minimum parameters needed by the connection factory. ibmmq
supports property-based routing (optimized for IBM® MQ), individual message acknowledgment for queues, and enhanced scalability for queue receivers.
IBM® MQ Service Specific Properties
This section describes the new configuration property elements that are used by the ibmmq
service only. These elements are not used by the jms
service.
Note: The routing properties listed below (the properties that begin with routing.
) are relevant for queues with property-based routing only (queues that have the property system.routing.property
specified). See Property Based Routing (PBR) with MQ.
Property | Required? | Description |
---|---|---|
queue.manager |
Optional1 | The name of the IBM® MQ queue manager that will receives calls. |
server.channel |
Optional1 | The server channel for client-to-server connections and client communications with the queue manager. Defaults to "SYSTEM.DEF.SVRCONN" . |
host |
Required when queue.manager is used |
Host name of the IBM® MQ server. |
port |
Required when queue.manager is used |
The port number that the IBM® MQ service is listening on for client connections. Defaults to "1414" . |
queue.read.interval |
Optional. Default value is 100ms (100 milliseconds). |
Allows you to specify the maximum time the ibmmq service waits between get calls (MQGET) to poll queues with active subscribers for new messages. You can specify the time interval syntax in milliseconds, seconds, minutes, or hours (spelled out or abbreviated). For example, all of the following are valid and represent typical values for this setting: 300ms, 300 milliseconds, 5s, 5sec, 5 secs, 5 seconds or 5seconds. |
queue.session.worker.count |
Optional | Used for high latency network scenarios. Use queue.session.worker.count to specify the number of worker threads for message acknowledgment and historical message gets. This number is per Queue Session (the number of queue sessions, used for reading messages from queues, is controlled by service property
queue.session.count ). Increasing the value of queue.session.worker.count can improve message throughput, especially in systems where there is significant latency on the network between the Gateway and the MQ Queue Manager. For high latency scenarios, suitable values for queue.session.worker.count might be 5 or 10 . |
routing.cache.size |
Optional. Default value is 1000000 (1 million). |
The maximum number of the message IDs stored in cache before the Gateway falls back to using message selectors to route messages. Cache refresh is performed when 80% of the size limit is reached, or whenever the value set in routing.cache.check.percentage is reached. Important: Cache refresh is only performed when refreshing would gain some cache space. If there are 800,000 messageIDs in the cache and there are 800,000 messages in the MQ Manager queue, then refreshing the cache will not gain space and is not performed. For more information, see Property Based Routing (PBR) with MQ. |
routing.cache.check.interval |
Optional. Default is 1 hour . |
Controls the interval between routing cache checks. A routing cache check compares the current number of entries in the historical message ID cache with the current depth of the queue in IBM MQ®. The cache is refreshed by rereading all messages from the queue if that would result in a reduction in cache size. The cache size reduction is performed if the new cache size is the value of the property routing.cache.check.percentage of the current cache size or smaller. If routing.cache.check.interval is set to 0 then no cache refresh is done. |
routing.cache.check.percentage |
Optional. Default value is 80 . |
Specifies the percentage of the configured routing.cache.size that, when reached, initiates a routing cache check. If a new message ID is added to the cache and the cache size now exceeds this percentage, a routing cache check is initiated. routing.cache.check.percentage also determines the threshold percentage for the historical message ID cache to be refreshed (see routing.cache.check.interval ). If routing.cache.check.percentage is set to 100 then only a time-based cache refresh is done. |
1Required if there is no initial context: property env.java.naming.factory.initial
is not set.
Individual Message Acknowledgment
The new ibmmq
service acknowledges queue messages individually. Individual message acknowledgement improves message throughput by allowing multiple messages to be sent to a client before receiving acknowledgments. The maximum pending acknowledgments setting for queues is controlled by service property queue.maximum.pending.acknowledgments
, or, if that property is not set, maximum.pending.acknowledgments
, and defaults to 100
.
maximum.pending.acknowledgments
can also be configured on a per queue basis within queue elements in the Gateway configuration file. For queue
elements, see Properties for the queue
Element.
Queue Message Distribution to All Consumers
The JMS 1.1 specification mandates that if a provider supports multiple message consumers on a queue, each message must be the delivered to one and only one consumer. The ibmmq
service introduces an extra feature: the ability to deliver each message to all consumers. This addition is useful in situations where, in conjunction with user-based message routing, the same user is logged into the application on multiple devices. In this case, the user will see the same messages on each device.
This new feature is controlled by the service property, queue.message.consumers
, with permitted values one
and all
. To provide greater control and override the settings for individual queues, message.consumers
can be set within queue
elements inside the service's properties
.
For compatibility with normal JMS behavior, the default setting is one for regular queues. For queues using property based routing (PBR), message.consumers
may only be set with all (the default value).
JNDI Context
The IBM® MQ JMS client libraries allow extensive control over the native MQ calls that the library makes by configuring the initialContext. If such control is desired, an initialContext can be defined using for example MQ Explorer. Once configured, the initialContext can be used with the ibmmq
service by making the generated .bindings file or ldap repository for the context available via the env.java.naming.provider.url
service property.
Currently, the ibmmq
service does not honor all of the settings in the InitialContext for queues, but support for these will be added in the future. When using topics, all of the settings are used.
Property Based Routing (PBR) with MQ
Note: For a detailed explanation of PBR, see Property-Based Routing (PBR) and Virtual Queues.
The ibmmq
service implements PBR with a special optimization to use a single shared queue subscription (per configured connection) for all subscribers to the various virtual queues. This optimization uses a cache of message IDs. The cache size is controlled by service property routing.cache.size
which is set as part of the queue configuration, as in the following example configuration:
<queue> <name>chat</name> <virtual.name.format>chat_%s</virtual.name.format> <virtual.name.resolver>com.acme.messaging.UserIdResolver</virtual.name.resolver> <system.name>chatsys</system.name> <system.routing.property>to</system.routing.property> <routing.cache.size>10000000</routing.cache.size> </queue>
The routing.cache.size
property specifies an upper limit on the number of message IDs to store in the cache. The default value is 1 million
. This value can be increased if needed without impacting memory dramatically. The value should be set to the maximum expected queue depth (maximum expected number of messages in the queue) for the underlying system queue (chatsys
in the above example). If the cache size is too small, new clients connecting and subscribing to a virtual queue might cause the ibmmq
service to issue queries to MQ using message selectors, which might impact performance.
Tuning IBM® MQ for Property Based Routing (PBR)
Follow these recommendations to tune IBM® MQ for PBR:
- Running IBM MQ® Queue Manager on z/OS? Turn on indexing by message ID (MSGID) on the physical queue(s) that have PBR enabled. This configuration improves performance, especially in cases where there are many messages (tens or hundreds of thousands) on the physical queue at a given time.
- Running IBM MQ® Queue Manager on another OS? If the number of messages on the queue at any given time becomes large (tens or hundreds of thousands), consider splitting virtual queues across multiple physical queues. Alternatively, when delivering historical messages to a new subscriber (historical messages are messages the Gateway
ibmmq
service has already fetched from the physical queue), you can force the use of message selectors rather than performing a get by messageID. To do this, set the routing cache size to0
(usingqueue
propertyrouting.cache.size
in the Gateway configuration file).
Notes
When clients subscribe to a queue without property-based routing enabled, and the default distribution option to deliver each message to just one consumer (message.consumers = one
) is used, it is recommended to increase the Queue Manager MsgMarkBrowseInterval
to NOLIMIT
, using an MQSC command such as ALTER QMGR MARKINT(NOLIMIT)
. Without this increase, a message that is received but not acknowledged for more time than the Queue Manager's MsgMarkBrowseInterval
might be redelivered, even if it is acknowledged after that time. For more information, see MsgMarkBrowseInterval (MQLONG) and ALTER QMGR in the IBMMQ documentation.