Oracle® Retail Integration Bus Operations Guide
Release 13.0
  Go To Table Of Contents
Contents

Previous
Previous
 
 

11 Performance Considerations

Performance Factors

The performance of each of these components is influential in the overall performance of the system:

There are other factors that determine the performance of the overall system. Some of these factors in a RIB environment are:

How to Measure RIB Performance

The performance of the RIB is a complicated subsystem to measure and involves not only host level performance, but database and application server subsystems performance. To make measurement of the RIB components timing characteristics available for analysis, the kernel code has been instrumented to log events as it processes events. The logging of these events is though log4j.

The timings are logged per adapter. Once the timings are enabled the events are logging continuously to the file.


Note:

See the section, "RIB Timing Logs", in this manual.

There is a post-processing tool included in RDMT to take the timing file and produce summary reports.


Note:

See the section, "RIB Timings Utility", in this manual.

How to Turn-on Timing

Control of the timing log is via the RIB Admin UI or the RIBLOGS log4j control file.


Note:

See the section, "RIB Timing Logs", in this manual.

How to Use the Timing Logs

Once the timing logs are created, they need to be post-processed and analyzed. The process to do that is to use the RDMT Timing Log Utility to post-process the adapter.timing.log file. This creates a .csv file that can then be viewed and printed by a spreadsheet tool (e.g. Microsoft Excel).


Note:

See the section, "RIB Timings Utility", in this manual.

The row headings that are displayed depend on the API type the adapter is interfaced to, PL/SQL or JavaEE and the adapter type; PUB, SUB, or TAFR. The above example is from a PL/SQL Publisher.

This table lists all of the column headings on the report and the definition of each.

TIMING_TYPE The type is the predefined interval of time across two or more timings log statements.
COUNT Count of similar timing_types for this msgtype.
AVERAGE_TIME (sec) TIME_SUM/COUNT
STANDARD_DEVIATION (sec) Math.sqrt((TIME_SQUARED_SUM - (TIME_SUM * TIME_SUM/COUNT)))/(COUNT - 1).
TIME_SUM (sec) Sum of all time intervals for this timing_type.
TIME_SQUARED_SUM (sec) Individual squares of timing intervals for this timing_type.
MIN_TIME (sec) Least time interval for this timing_ type.
MAX_TIME (sec) Max time interval for this timing_type.
THRESHOLD (sec) Default Threshold is 10 sec, if any time interval takes more than 10 sec its tracked under over_threshold.
OVER_THRESHOLD_COUNT Number of over threshold intervals.
OVER_THRESHOLD_SUM (sec) Summation of all such intervals that are greater than threshold.
OVER_THRESHOLD_AVG (sec) Average all such intervals that are greater than threshold.

This table lists the currently pre-defined time intervals interpreted by the timings logs processor utility. They are the row headings in the report under the column heading Timing Types. The description is the definition of interval calculation.

Timing Type Description
PUB_B4_GETNXT_CALL Time interval between start of the publisher and the actual GETNXT call.
PUB_TIME_IN_GETNXT_CALL Time taken by the GETNXT call to the plsql app.
PUB_TIME_IN_EJB_PUBLISH_CALL Time taken for the publish call in the EJB, includes RIB overhead surrounding the actual publish to the JMS.
PUB_TOTAL_PUBLISH_TIME Time taken for the complete PUB process = GETNXT + hospital dependency + publish + commit.
PUB_TIME_IN_REAL_JMS_PUBLISH Time taken to publish a message to the AQ JMS.
SUB_TIME_IN_CONSUME_CALL Time taken by the CONSUME call to the plsql app.
SUB_TOTAL_SUBSCRIBE_TIME Time taken for the complete SUB process = CONSUME/INJECT + hospital dependency + subscribe + commit.
SUB_TIME_IN_EJB_SUBSCRIBE_CALL Time taken for the subscribe call in the EJB, includes RIB overhead surrounding the actual subscribe.
SUB_TIME_IN_INJECT_CALL Time taken by the INJECT call to the java app.
TAFR_TOTAL_MSGPROCESS_TIME Time taken in the complete message tafring Process = TAFRing + hospital dependency + publish + RIB overhead
TAFR_TIME_IN_EJB_CALL Time taken for the TAFR call in the EJB, includes RIB overhead surrounding the actual TAFRing
TAFR_TIME_IN_REAL_JMS_PUBLISH_EJB Time taken by the TAFR to publish a message to the AQ JMS.

Example Timing Analysis - PL/SQL PUB

This a partial extract of a post-processor report on an RMS Order_pub adapter timing log.

Timings for the Period 09:00:00 to 09:59:59

TIMING_TYPE COUNT AVG_TIME STD_DEV TIME_SUM
PUB_B4_GETNXT_CALL 220 0.02239 0.00041 4.926
PUB_TIME_IN_GETNXT_CALL 220 0.15503 0.0067 34.107
PUB_TIME_IN_EJB_PUBLISH_CALL 220 1.82395 0.05014 401.269
PUB_TOTAL_PUBLISH_TIME 220 2.11173 0.04992 464.58
PUB_TIME_IN_REAL_JMS_PUBLISH_EJB 220 1.81753 0.05012 399.856

In this example the messages were published between 09:00 - 10:00 AM. In this example the messages were published between 09:00 - 10:00 AM.

T4 - PUB_TOTAL_PUBLISH_TIME is the total time taken for the complete PUB process.

  • T1 - PUB_B4_GETNXT_CALL is the time interval between start of the GETNXT EJB and the PL/SQL GETNXT API call.

  • T2 - PUB_TIME_IN_GETNXT_CALL is time taken by the PL/SQL API GETNXT call.

  • T3 - PUB_TIME_IN_EJB_PUBLISH_CALL is the time taken for the EJB publisher call.

    • T5 - PUB_TIME_IN_REAL_JMS_PUBLISH is the time taken to publish a message to the JMS

T3 = T5 + (RIB Overhead payload creation)

T4 = T1 + T2 + T3 + (Hospital Dependency Checks)

In this example the data points give these insights into the RIB performance.

  • "The average time to publish a message is 2.1 seconds.

  • The time spent in the PL/SQL API is 0.15 seconds/message

  • The time spent in the call to the JMS is 1.8 seconds/message


Note:

This is an illustration and not a measure of actual through-put or numbers that can be extrapolated to indicate volume performance. The number of message needed to arrive at a calculation of through-put would require much higher counts and across a broad spectrum of time and system load. Other factor including average size of message used is also a factor.

Multi-Channel Adapters

A channel is a solution approach to maintaining the previous RIB release concept of a "Logical Channel", also known as multi-threading.

Multi-channel is concept to logically partitioning the flow of messages within the JMS topic so that multiple publisher and subscriber can simultaneously use the same JMS topic without any contention or interference with each other and preserving publication message ordering within the logical channel.

Every adapter instance of a publisher, subscriber, or TAFR, configured in the RIB is considered to belong to a logical channel for processing messages. By multi-channel adapters we mean multiple adapter instances for the same message family, each processing messages asynchronously and in parallel.

There are critical rules of behavior that have to be observed and enforced to maintain the two primary RIB functional requirements of once-and-only-once successful delivery and guaranteed sequencing of messages within a message family.

To ensure that these rules are followed and to make the tasks of configuration of the RIB to support a multi-channel message flow as simple as possible, the process has been integrated into the RIB App Builder tools.

When multiple channels are being considered, they must be defined and configured across all publisher, subscriber, and TAFRs that participate in an end-to-end message flow to and from all Oracle Retail applications for that message family. The RIB App Builder tools have checks and verification logic to prevent deployment of incomplete flows.

Multi-channels can be a valuable tool to increase performance, but it does not help in every situation. There is overhead and complexity associated with implementing multiple channels so they should not be considered unless a defined and performance problem exists. The process of adding multi-channels to a message family should be part of a performance test and tuning process.

Logical Channels and threadValue

Each messaging RIB component involved in publishing or subscribing to a logical channel is distinctly identified by a JMS Message property known as "threadValue" with a specific value. This JMS message property and the value it contains define the logical channel.

JMS Message properties are user-defined additional properties that are included with the message. Message properties have types, and these types define application-specific information that message consumers can use to select the messages that interest them.

So each RIB subscriber has the "threadValue" property and this value as part of its JMS Durable Subscriber selector and each RIB publisher sets the "threadValue" JMS message property to a specific value for each message it publishes.

Oracle Retail RIB components are capable of being multi-channeled by making configuration changes to the system. The base RIB configuration, as shipped GA, provides each Message Family with one channel where all components set or look for "threadValue" of 1 (one). The naming convention and the RIB kernel code identify the RIB adapters by adding the logical channel to the end of the adapter class name.

Alogrithm Used to Calculate Channel

Channels are calculated based on Business object ID(BOID) found in the RibMessages <id> tag. The algorithm used to calculate is as follows.

MOD(MD5(family + ":" + businessObjectId)%maxChannelNumber) + 1
  • First the algorithm calculates the message digest of the string family+":"+businessObjectId which produces a unique number.

  • Then this number is divided by the maxChannelNumber, which is calculated by the number of configured channels for that message family.

  • A 1 is added to the result so that the channel number is always greater than 0.

For example:

Family = Alloc
BusinessObjectID (BOID) = 10202123
MaxChannelNumber = 7 (Total number of channels configured for the Alloc family)
Then the channel number for the BOID is calculated as
sMOD(MD5(Alloc + ":" + 10202123)%7) + 1 = 4
which means that all the messages that have BusinessObjectID of 10202123
are ALWAYS sent through channel 4 (Alloc_pub_4).

Note:

The channels have to be configured throughout the integration flow using the rib-app builder tool.

Example of a Message Family Flow with a TAFR:

Alloc_pub_1

Alloc_tafr_1

StockOrder_sub_1

How to Configure a Multi-Channel Flow

Generalized Process

  1. Determine the Family to multi-channel

  2. Examine the rib-integration-flows.xml to identify all participants in the full flow.

  3. In the rib-home modify the appropriate configuration files for each of the rib-<apps>.

    1. rib-<app>-adapters.xml

    2. rib-<app>-adapter-resources.properties

  4. For PL/SQL Application edit the RIB_SETTINGS table.

  5. Compile and Deploy

Example

This example is to configure the Alloc message flow with five channels. Alloc is a complex flow in that it has multiple Oracle Retail application subscribers and a TAFR that transforms the messages from one family to another; Alloc to StockOrder.

Backup the following files.

  • "rib-home/application-assembly-home/rib-rms/rib-rms-adapters.xml

  • rib-home/application-assembly-home/rib-rms/rib-rms-resources.properties.

The following is the message flow for the Alloc Family from rib-integration-flows.xml that this example uses.

<message-flow id="1">            
<node id="rib-rms.Alloc_pub" app-name="rib-rms" adapter-class-def="Alloc_pub" type="DbToJms">
<in-db>default</in-db>
<out-topic>etAllocFromRMS</out-topic>
</node>
<node id="rib-tafr.Alloc_tafr" app-name="rib-tafr" adapter-class-def="Alloc_tafr" type="JmsToJms">
<in-topic>etAllocFromRMS</in-topic>
<out-topic name="topic-name-key-iso">etStockOrdersISO</out-topic>
<out-topic name="topic-name-key-wh">etStkOrdersFromRIBToWH{*}</out-topic>
</node>
<node id="rib-sim.StockOrder_sub" app-name="rib-sim" adapter-class-def="StockOrder_sub" type="JmsToDb">
<in-topic>etStockOrdersISO</in-topic>
<out-db>default</out-db>
</node>
<node id="rib-rwms.StockOrder_sub" app-name="rib-rwms" adapter-class-def="StockOrder_sub" type="JmsToDb">
<in-topic>etStkOrdersFromRIBToWH1</in-topic>
<out-db>default</out-db>
</node>
</message-flow>

RIB-RMS

  1. Modify rib-rms-adapters.xml to add multiple channels.

    Here is a snippet of rib-rms-adapters.xml

    <publishers>
    <timer-driven id="Alloc_pub_1" initialState="running" timeDelay="10">
    <timer-task>
    <class name="com.retek.rib.app.getnext.impl.GetNextTimerTaskImpl"/>
    <property name="maxChannelNumber" value="5" />
    </timer-task>
    </timer-driven>
    <timer-driven id="Alloc_pub_2" initialState="running" timeDelay="10">
    <timer-task>
    <class name="com.retek.rib.app.getnext.impl.GetNextTimerTaskImpl"/>
    <property name="maxChannelNumber" value="5" />
    </timer-task>
    </timer-driven>
    <timer-driven id="Alloc_pub_3" initialState="running" timeDelay="10">
    <timer-task>
    <class name="com.retek.rib.app.getnext.impl.GetNextTimerTaskImpl"/>
    <property name="maxChannelNumber" value="5" />
    </timer-task>
    </timer-driven>
    <timer-driven id="Alloc_pub_4" initialState="running" timeDelay="10">
    <timer-task>
    <class name="com.retek.rib.app.getnext.impl.GetNextTimerTaskImpl"/>
    <property name="maxChannelNumber" value="5" />
    </timer-task>
    </timer-driven>
    <timer-driven id="Alloc_pub_5" initialState="running" timeDelay="10">
    <timer-task>
    <class name="com.retek.rib.app.getnext.impl.GetNextTimerTaskImpl"/>
    <property name="maxChannelNumber" value="5" />
    </timer-task>
    </timer-driven>
    
  2. Modify rib-rms-adapter-resources.properties.

    Alloc_pub_1.name=Alloc Publisher, channel 1   
    Alloc_pub_1.desc=Publisher for the Alloc family through channel 1.      
    Alloc_pub_2.name=Alloc Publisher, channel 2   
    Alloc_pub_2.desc=Publisher for the Alloc family through channel 2.      
    Alloc_pub_3.name=Alloc Publisher, channel 3   
    Alloc_pub_3.desc=Publisher for the Alloc family through channel 3.      
    Alloc_pub_4.name=Alloc Publisher, channel 4   
    Alloc_pub_4.desc=Publisher for the Alloc family through channel 4.      
    Alloc_pub_5.name=Alloc Publisher, channel 5   
    Alloc_pub_5.desc=Publisher for the Alloc family through channel 5.
    

RIB-TAFR

  1. Modify rib-tafr--adapters.xml to add channels for a family.

    <tafrs>       
    <message-driven id="Alloc_tafr_1" initialState="running" 
    tafr-business-impl="com.retek.rib.domain.tafr.bo.impl.AllocToStockOrderFromRibBOImpl" />
    <message-driven id="Alloc_tafr_2" initialState="running" 
    tafr-business-impl="com.retek.rib.domain.tafr.bo.impl.AllocToStockOrderFromRibBOImpl" />
    <message-driven id="Alloc_tafr_3" initialState="running" 
    tafr-business-impl="com.retek.rib.domain.tafr.bo.impl.AllocToStockOrderFromRibBOImpl" />
    <message-driven id="Alloc_tafr_4" initialState="running" 
    tafr-business-impl="com.retek.rib.domain.tafr.bo.impl.AllocToStockOrderFromRibBOImpl" />
    <message-driven id="Alloc_tafr_5" initialState="running" 
    tafr-business-impl="com.retek.rib.domain.tafr.bo.impl.AllocToStockOrderFromRibBOImpl" />
    
  2. Modify rib-tafr-adapters-resources.properties.

    Alloc_tafr_1.name=AllocToStockOrder TAFR, channel 1
    Alloc_tafr_1.desc=TAFR for converting Allocation messages to StockOrders and routing them
    to the correct warehouse or store system
    
    
    Alloc_tafr_2.name=AllocToStockOrder TAFR, channel 2
    Alloc_tafr_2.desc=TAFR for converting Allocation messages to StockOrders and routing them
    to the correct warehouse or store system
    
    
    Alloc_tafr_3.name=AllocToStockOrder TAFR, channel 3
    Alloc_tafr_3.desc=TAFR for converting Allocation messages to StockOrders and routing them
    to the correct warehouse or store system
    
    
    Alloc_tafr_4.name=AllocToStockOrder TAFR, channel 4
    Alloc_tafr_4.desc=TAFR for converting Allocation messages to StockOrders and routing them
    to the correct warehouse or store system
    
    
    Alloc_tafr_5.name=AllocToStockOrder TAFR, channel 5
    Alloc_tafr_5.desc=TAFR for converting Allocation messages to StockOrders and routing them
    to the correct warehouse or store system
    

RIB-SIM

  1. Modify rib-sim-adapters.xml to add channels for a family.

    <subscribers>
    <message-driven id="StockOrder_sub_1" initialState="running"/>
    <message-driven id="StockOrder_sub_2" initialState="running"/>
    <message-driven id="StockOrder_sub_3" initialState="running"/>
    <message-driven id="StockOrder_sub_4" initialState="running"/>
    <message-driven id="StockOrder_sub_5" initialState="running"/>
    
  2. Modify rib-sim-adapters-properties.properties.

    StockOrder_sub_1.name=StockOrder Subscriber, channel 1
    StockOrder_sub_1.desc=Subscriber for the StockOrder family through channel 1.
    
    
    StockOrder_sub_2.name=StockOrder Subscriber, channel 2
    
    StockOrder_sub_2.desc=Subscriber for the StockOrder family through channel 2.
    
    
    StockOrder_sub_3.name=StockOrder Subscriber, channel 3
    StockOrder_sub_3.desc=Subscriber for the StockOrder family through channel 3.
    
    
    StockOrder_sub_4.name=StockOrder Subscriber, channel 4
    StockOrder_sub_4.desc=Subscriber for the StockOrder family through channel 4.
    
    
    StockOrder_sub_5.name=StockOrder Subscriber, channel 5
    StockOrder_sub_5.desc=Subscriber for the StockOrder family through channel 5.
    

RIB-RWMS

  1. Modify rib-rwms-adapters.xml to add channels for a family.

    <subscribers>
    <message-driven id="StockOrder_sub_1" initialState="running"/>
    <message-driven id="StockOrder_sub_2" initialState="running"/>
    <message-driven id="StockOrder_sub_3" initialState="running"/>
    <message-driven id="StockOrder_sub_4" initialState="running"/>
    <message-driven id="StockOrder_sub_5" initialState="running"/>
    
  2. Modifyrib-rwms-adapters-properties.properties.

    StockOrder_sub_1.name=StockOrder Subscriber, channel 1
    StockOrder_sub_1.desc=Subscriber for the stockorder family through channel 1.
    
    
    StockOrder_sub_2.name=StockOrder Subscriber, channel 2
    StockOrder_sub_2.desc=Subscriber for the stockorder family through channel 2.
    
    
    StockOrder_sub_3.name=StockOrder Subscriber, channel 3
    StockOrder_sub_3.desc=Subscriber for the stockorder family through channel 3.
    
    
    StockOrder_sub_4.name=StockOrder Subscriber, channel 4
    
    StockOrder_sub_4.desc=Subscriber for the stockorder family through channel 4.
    
    
    StockOrder_sub_5.name=StockOrder Subscriber, channel 5
    StockOrder_sub_5.desc=Subscriber for the stockorder family through channel 5.
    

Edit the RIB_SETTINGS table

When a PL/SQL Publishing adapter is multi-channeled, the application code needs to designate the message to a specific thread. In order to do this, a change needs to be made in the RIB_SETTINGS table.

Find the Family of messages that is being multi-channeled, and adjust the column NUM_THREADS to the appropriate number. In this example the number will be set to 4 for the Alloc Family.

Compile and Deploy

Using the RIB Installer or the RIB App Builder command line tools, compile and deploy the new rib-<app>.ears.

Message Aggregation

In order to improve performance of GETNEXT, messages are aggregated before publishing to the JMS. Aggregation of payloads is performed on a per family basis. These properties must be used when RIB is being integrated to the PL/SQL applications. Hence, modifications need to be made for the respective rib-<pl-sql> apps on the RIB end.

maxNodesPerMessages - Maximum number of ribMessages per one RibMessage Envelope.

messagePerCommit - Maximum number of RibMessage's sent for a commit. In order to not overload the JMS with huge payloads this property must be set.

These properties should exist in the rib-<pl-sql>.properties file.

Items.maxNodesPerMessages=2

Meaning 2 ribMessages per RibMessage.

Items.messagePerCommit=5

Meaning 2 ribMessages per commit.

How to Configure Message Aggregate

rib-rms is taken as an example in this configuration.

  • Edit the following file in rib-home

    • rib-home/application-assembly-home/rib-rms/rib-rms.properties

  • Add the following properties

    • Items.maxNodesPerMessagess=5

    • Items.MessagePerCommit=2

  • Using the app-builder tool compile/deploy the application.

    • rib-app-compile.sh

    • rib-app-deployer.sh -deploy-rib-app-ear rib-rms

For example, if there are 15 payloads waiting to be published in RMS, based on the above configuration one should be able to see the following. The scenario is depicted pictorially in the figure below.

Surrounding text describes payloads.png.