Saturday, November 30, 2019

Throttling JMS adapters in SOA Suite

When working with JCA adapters that need to process huge amounts of transactions per second it's important to have some sort of control over the processing. Failing to do so can lead to memory issues and stuck threads on your servers. In this blog I will show you how you can implement a throttling mechanism on inbound JMS adapters. This way you can control the number of transactions processed per time interval. I will also show you how you can adjust the properties run-time in the Enterprise Manager.

The following two properties will be used for our JMS adapter:

1) adapter.jms.receive.threads: Specifies the number of poller threads that are created when an endpoint is activated. The default is 1.
2) minimumDelayBetweenMessages: Default is False, or no delay. Inbound-only. This property is configured in milliseconds. Ensures that there at least will be MILLI_SECONDS delay between two consecutive messages posted to the downstream composite application.


Note that minimumDelayBetweenMessages is effective per adapter polling thread. If you have configured multiple adapter polling threads, this setting controls the delay between messages processed by each thread only.
 


Source: https://docs.oracle.com/middleware/1221/adapters/develop-soa-adapters/GUID-2BB20502-6F62-462F-A490-3AF301AB6089.htm#TKADP2128

I'm working with SOA Suite 11g but these properties exist for 12c too as seen in the Oracle documentation.

These properties are set in the composite.xml as part of the service definition that represents your JCA adapter, as follows:


When setting the values you have to think about what number of transactions per second is desirable. You also need to take the number of managed servers in your environment into account. The following formula could be helpful:

(Number of Managed Servers x thread count) / (minimumDelayBetweenMessages / 1000) 

Calculation example:
-There are two managed servers.
-Each adapter will handle two threads at the same time (set via property adapter.jms.receive.threads = 2).
-Each thread waits at least half a second before processing a new transaction (set via property minimumDelayBetweenMessages = 500ms).

When the formula is applied that means (2 x 2) / (500  / 1000) = 8 transactions per second will be processed per JMS queue.


It's possible to adjust these values run-time. This is done via the Enterprise Manager. Navigate to your SOA Composite and then the Service/Reference Properties:

Adjust the values and click 'Apply'.


Let's do some testing now. To view the results unambiguously, I will just use one active managed server with one queue and one thread per adapter so we can clearly see the time interval.

I will use the following values for the properties: 

<property name="adapter.jms.receive.threads">1</property>
<property name="minimumDelayBetweenMessages">2000</property>


Now according to the formula (Number of Managed Servers x thread count) / ( minimumDelayBetweenMessages / 1000) that means we have (1 x 1) / (2000 /1000) = 0,5 transaction per second. Or 1 transaction every 2 seconds per queue.

I will dump a batch of messages on one JMS queue. Then we will check the logs how the JMS adapter has processed those messages. Of course we would like to see that indeed 1 message was processed every 2 seconds.

First we need to adjust the Diagnostic Logging Level. This is done via the Log Configuration in the Enterprise Manager. Set the level for the oracle.soa.adapter logger to TRACE. This is the logging for JCA adapters.


 

When the batch of messages is imported on the JMS queue to be processed we can check our logging:

 
If we look at the Time column we can verify that the JMS adapter indeed processed 1 message every 2 seconds, great!

No comments:

Post a Comment