How messages are processed in non-ASF mode
In non-ASF mode threads are active from the moment that the listener port is started. The number of active threads is dictated by the value specified for Maximum Sessions. The number of threads specified in Maximum Sessions are active, regardless of the number of messages available to be processed. Each active thread is an individual physical network connection.
If we are using IBM MQ v7.0 or later as our messaging provider, it is possible to have up to ten threads sharing a single physical network connection.
For WebSphere Application Server v7 and later, listener ports are stabilized. We should plan to migrate the IBM MQ message-driven bean deployment configurations from using listener ports to using activation specifications. For more information about how to configure activation specifications for non-ASF mode, see Configure activation specifications for non-ASF mode. However, we should not begin this migration until we are sure the application does not have to work on application servers earlier than WAS v7. For example, if we have an application server cluster with some members at v6.1 and some at a later version, we should not migrate applications on that cluster to use activation specifications until after we migrate all the application servers in the cluster to the later version.
Message processing in non-ASF mode
You activate non-ASF mode by specifying a non-zero value for the NON.ASF.RECEIVE.TIMEOUT message listener service custom property. NON.ASF.RECEIVE.TIMEOUT acts as a switch that turns off ASF mode, and also as a timeout value for the receive() method.
The following message listener service custom properties do not work in non-ASF mode:
- SERVER.SESSION.POOL.REAP
- SERVER.SESSION.POOL.UNUSED.TIMEOUT
- SERVER.SESSION.POOL.UNUSED.TIMEOUT.Ipaname
The following diagram shows how message processing takes place between WAS and IBM MQ in non-ASF mode:
Figure 1. Message processing in non-ASF mode
As shown in the diagram, when the message listener service is operating in non-ASF mode, messages are processed in the following way:
- When the listener port is started, it gets one thread from the message listener service thread pool.
- The listener port opens a connection to the IBM MQ queue manager on the thread and creates a JMS message consumer. The message consumer listens to the JMS destination which the listener port is configured to listen to.
- The listener port creates a transaction to manage the message processing.
- The thread calls the receive() method on the message consumer to listen for messages at the destination. If the receive() method does not detect a message in the time specified for NON.ASF.RECEIVE.TIMEOUT, the application server rolls back the active transaction and starts a new one. The thread then starts calling the receive() method again.
- When the message consumer detects a message it checks whether the message is suitable for the DB that is using the listener port.
- If the message is suitable, the receive() method takes it off the destination and sends it to the thread.
- The thread invokes the onMessage() method of the MDB on the message consumer, and the message is processed.
- If the message finishes processing successfully, the transaction commits. If the message does not process successfully, the transaction rolls back.
- A new transaction is started and the message consumer calls the receive() method to listen for new messages.
The number of threads an MDB can process concurrently is determined by the value of the Maximum Sessions property for the listener port. If we set Maximum Sessions to the default value of 1, this means that the MDB can only process one message at a time. To process more than one message concurrently, we can do this in ASF mode by setting Maximum Sessions to a value higher than 1. For example, if we set Maximum Sessions to 2, messages are processed in the following way:
- When the listener port is started, it gets two threads from the message listener service thread pool.
- The listener port creates a message consumer and a transaction on each thread. The message consumers listen to the destination which the listener port is configured to listen to.
- Both message consumers call the receive() method to listen for messages on the destination. The consumers compete to get messages from the destination.
- When one of the consumers successfully retrieves the message, it processes it by calling the onMessage() method of the MDB. The other message consumer keeps on calling the receive() method to listen for messages on the destination.
How to avoid unwanted transaction timeouts
If our messaging system is running in non-ASF mode, to avoid unwanted transaction timeouts, we must allow a sufficient amount of time for processing to be completed before the total transaction lifetime timeout is reached. Therefore, make sure that the value specified for the NON.ASF.RECEIVE.TIMEOUT message listener service custom property is smaller than the value specified for the Total transaction lifetime timeout transaction service property, and also that the difference between the values of the two properties is greater than the amount of time that the onMessage() method of the message-driven bean (MDB) takes to process the message.
As the following example shows, if these properties are not correctly configured, transactions can time out before they are completed. This is because the thread begins calling the receive() method as soon as the transaction is created. In the following example, NON.ASF.RECEIVE.TIMEOUT is set to 110000 milliseconds (110 seconds), Total transaction lifetime timeout is set to 120 seconds and the onMessage () method of the DB takes 15 seconds to process a message. The example supposes that a message does not appear at the destination until the receive() method has almost timed out:
- The listener port starts. It allocates a thread from the thread pool and creates a transaction and a message consumer on the thread.
- The thread calls the receive() method to listen for messages.
- After 110 seconds a message appears at the destination.
- The thread removes the message from the destination and calls the onMessage() method of the MDB to begin processing the message.
- 10 seconds later, the transaction timeout is reached. The application server marks the transaction for rollback.
- 5 seconds later, the onMessage() method finishes processing the message and tries to commit the transaction.
- The total amount of time that has elapsed since the transaction was started is 125 seconds (110 seconds waiting for a message, plus 15 seconds to process the message). As this is longer than the transaction timeout, the application server prevents the transaction from being committed, and it is rolled back.
For further information about how to configure the NON.ASF.RECEIVE.TIMEOUT and Total transaction lifetime timeout properties to avoid unwanted transaction time outs, see the related tasks.
Subtopics
- Configure activation specifications for non-ASF mode
Activation specifications are the standardized way to manage and configure the relationship between a message driven bean (MDB) running in WebSphere Application Server and a destination in IBM MQ. This task explains how to configure WAS to use non-ASF mode to processes messages.
Related:
Strict message ordering using non-ASF listener ports Configure transaction properties for an application server Avoiding transaction timeouts in non-ASF mode Configure activation specifications for non-ASF mode Message listener service custom properties IBM MQ messaging provider connection factory settings IBM MQ messaging provider queue connection factory settings IBM MQ messaging provider topic connection factory settings Listener port settings Stabilized features of WAS traditional