Oracle® Retail Integration Bus Cloud Service Operations Guide Release 19.0.000 F22950-01 |
|
Previous |
The chapter discusses the performance characteristics of RIB, the factors that affect it, and a process to test it.
Performance of RIB within a customer site is critical to the performance of the business, and is determined by factors specific to a given deployment. Because of this is, a Performance Test is recommended as part of every deployment plan. Even if formal testing is not planned, the use of the tools and processes discussed can measure the relative performance of the RIB sub-system and can be used to diagnose bottlenecks.
It is beyond the scope of this document to discuss all of the tools and techniques available at the host, network, database, and application server level.
See the Oracle Integration Bus Implementation Guide.
The performance of each of these components affects the overall performance of the system:
Application Server topology and configuration.
RIB deployment approach.
Hardware sizing and configuration of the following:
RIB hosts
Applications connected to RIB
JMS provider host
RIB Hospital hosts
There are other factors that determine the performance of the overall system. Some of these factors in a RIB environment are:
Number of channels configured
Number of messages present in the topic
Size of the message
Database clustering
Application Server topology
Number of TAFRs in the processing of the message
Message aggregation
For each RIB message family, volume requirements are almost always described for the end-to-end message flow, from publication to completion of subscription by all Oracle Retail applications. Retail businesses express volume requirements in terms of details per hour and per day.
Each message family has its own volume requirements, and any given family may have an intermediate component between the originating publication and the end subscriber. These components are called TAFRs (Message Transform, Filtering, and Routing). This is an important concept, because it means that in a given flow, a message published by the source system may be subscribed to and then re-published by a TAFR before it is subscribed to by the destination application. This is true for many Message Families.
The following are examples of volume requirements:
Family | Details Per Day | Details Per Hour |
---|---|---|
Purchase Orders | 355,000 | 355,000 |
ASN Inbound | 19,200,000 | 19,200,000 |
Appointments | 240,000 | 30,000 |
PO Receipt | 240,000 | 30,000 |
Store Receipt | 4,000,000 | 2,000,000 |
Transfers | 1,000,000 | 250,000 |
Stock Order Allocation | 600,000 | 75,000 |
Stock Order Transfer | 1,000,000 | 75,000 |
Stock Order Status | 600,000 | 75,000 |
ASN Outbound (BOL) | 285,000 | 285,000 |
Promotions | 5,000,000 | 250,000 |
Item Locations | 1,000,000 | 300,000 |
Items | 100,000 | 20,000 |
Note: Although these examples are for illustration, they are representative of actual customer requirements. |
Message construction is the same for all Oracle Retail Publishing applications and RIB adapters. There are configuration control points that allow flexibility in the size of the message. The application side has the ability to specify the number of details per message. There is a RIB setting that controls the aggregation of the messages (ribMessage) within the larger RibMessages envelope. There is a setting that controls the number of RibMessages published within a commit to the JMS.
See "Message Aggregation."
RIB is designed to support parallel message handling to increase throughput by way of a mechanism called multi-channel, which logically partitions the flow of messages within the JMS topic so that multiple publishers and subscribers can simultaneously use the same JMS topic without contention or interference and preserve publication message ordering within the logical channel.
Every adapter instance of a publisher, subscriber, or TAFR configured in RIB is considered to belong to a logical channel for processing messages. Multi-channel adapters are multiple adapter instances for the same message family, each processing messages asynchronously and in parallel. When multiple channels are used, 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.
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 included with the message. Message properties have types to define application-specific information that message consumers can use to select the messages that interest them. Each RIB subscriber has the "threadValue" property, and this value is 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 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.
The diagram below demonstrates the multi-channeling of the Purchase Order flow to two channels.
RIB performance is judged by the average time a message family detail takes to flow from a publisher to consumption by all active subscribers. This is not a straightforward measurement.
Message throughput is not a calculation of the sum of the individual message times. Although the average time per message will remain fixed, messages are processed in parallel. So the total time to process n messages on a single channel will not be the serial sum of the individual messages.
Additionally, it is possible to configure multiple logical channels to increase overall throughput.
It is important to understand the average messages in an integration flow. Where interfaces are separated into messages families with differing payloads per message type, these calculations can be difficult. This section outlines an approach for arriving at averages using the sample XML files that ship with RIB.
RIB delivers sample files generated for each message family.
Note: Several families have variable types of details per header so a close investigation is required to understand what the relationship is and what a representative message can be. |
In practice, of course, this size will vary depending on the number of characters that a description element may contain, but for performance testing calculations, this is a reasonable start for calculations.
Note: An alternative is to use the audit feature of RIB. These messages can then be used to estimate the average sizes. |
The RIB message envelope, called a RibMesssages contains a variable number of ribMessage nodes. Within a ribMessage node is a message family payload. A minimum payload for this exercise is defined as one header and a variable number of details.
The general process to determine the size in bytes of a message family message per detail using the RIB sample xml messages and xsds is as follows:
Determine the RIB envelope size (RibMessages elements + ribMessage elements).
Determine the size of a single header.
Determine the size of a detail.
RIB has a standard message envelope (RIBMessages.xsd) that can be easily calculated exclusive of the message family payload.
ribMessage header elements no payload | 823 Bytes |
RibMessages header elements | 324 Bytes |
RibMessages with 1 or no payload | 1147 Bytes |
Each message family is comprised of message type and an associate payload (for example, POCre uses PODesc.xsd). These relationships are defined in the Oracle Retail Enterprise Integration Guide.
The sample XML messages for each release are packaged in the functional artifacts war file and with RDMT in the rib-home/tools-home/rdmt/testmsgs directory.
Select the message payload file and look at the byte count. This will always be 1 header and 1 detail. Be aware that this relationship varies by family and can be complex for some message types (for example, ItemCre and ItemDesc.xsd) where optional details can be present.
Select the payload file and remove all detail nodes and look at the byte count. This will be the standard header. Use the same procedure for the details. This will be the detail size.
Example Message - PODesc | |
Header Size (PODesc no detail) | 9413 |
1 Detail Size (PODtl) | 1943 |
The next step is to determine the average number of details per message. This will vary based on the business needs and the selected RIB configuration.
See "Message Aggregation."
Using the desired number of details per message, this calculation is the result:
Total 1 RibMessages + 1 ribMessage + 1 Header + 1 Detail | Avg Message Size |
For example:
Total 1 RibMessages + 1 ribMessage + 1 PODesc + 1 PODtl | 12,053 |
ribMessage header elements no payload | 823 |
RibMessages header elements | 324 |
RibMessages with 1 rM no payload | 1147 |
Message - PODesc | |
Header Size (PODesc no detail) | 9413 |
1 Detail Size (PODtl) | 1943 |
Total 1 RibMessages + 1 ribMessage + 1 PODesc + 1 PODtl | 12,053 |
The following is an example using the default settings.
RIB messages created by the Order publishing adapter (details per message):
Contains a maximum of 20 ribMessages per RibMessage.
Has 20 details per PODesc payload in a ribMessage.
For a 400 Details PO Message the calculation is:
RibMessage = 1 RibMessages header + 20 ribMessage headers + 20 PODesc + 400 PODtls
# ribMessage nodes | 20 |
# Details | 400 |
RibMessages Header (1) | 324 |
ribMessage Header (20) | 16,460 |
PODesc (20) | 188,260 |
PODtl (400) | 777,200 |
Total Bytes/Msg | 982,644 |
Using the example volume requirement for the Purchase Orders, and using the same RIB message configuration settings:
Details per hour requirement (Total Through-put) | 355,000 |
Details per Message | 400 |
Total messages per hour (355,000/400) | 887 |
Message/sec required (982 KB each - 60*60/887) | 4.058 |
So:
End-to-End — 1 message with 400 details can take a max of 4.058 seconds.
End-to-End — 982,644 Bytes can take a max of 4.058 seconds (which in this example is 400 details).
So:
982644 Bytes/4.058 sec = 242149.83 bytes/sec = 0.2421498 MB/sec Total end-to-end throughput to meet the Purchase Order example requirements.
These are end-to-end processing time requirements across the entire message flow from Publisher to Subscription completion.
The following diagram is a generic message flow.
To continue the Purchase Order example, the requirements and timings have to be broken down further. The Purchase Order flow has a TAFR as well as multiple subscribers. For purposes of this example, consider the Subscribers Consume times as equivalent. As the diagram depicts, for a flow like the Purchase Orders, there are multiple components and for a single message to flow there will be, at a minimum, a message published twice and subscribed twice, as well as a marshalling and un-marshalling of the message twice (Family dependent). There will be at least one, and possibly two, Hospital Dependency checks as well.
The following diagram is a logical view of the Oracle Retail Purchase Order flow.
The following diagram is a functional, detailed view of the Oracle Retail Purchase Order flow.
RIB performance is a complex subsystem to measure. It involves not only host level performance, but database, network, and application server subsystems performance. To measure the RIB components' timing characteristics available for analysis, the RIB kernel code logs events as it processes them. The logging of these events is through log4j2; timings are logged per adapter. Once the timings are enabled the events log continuously to the file. The RIB RDMT supplies a post-processing tool to take the timing file and produce summary reports.
This table lists the currently predefined times that are tracked in the RIB Timings logs. The description is the definition of interval calculation.
Timing Type | Description | |
---|---|---|
T1 | PUB_B4_GETNXT_CALL | Time interval between start of the publisher and the actual GETNXT call. |
T2 | PUB_TIME_IN_GETNXT_CALL | Time taken by the GETNXT call to the plsql app. |
T3 | 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. |
T4 | PUB_TOTAL_PUBLISH_TIME | Time taken for the complete PUB process = GETNXT + hospital dependency + publish + commit. |
T5 | PUB_TIME_IN_REAL_JMS_PUBLISH | Time taken to publish a message to the AQ JMS. |
T6 | SUB_TIME_IN_CONSUME_CALL | Time taken by the CONSUME call to the plsql application. |
T7 | SUB_TOTAL_SUBSCRIBE_TIME | Time taken for the complete SUB process = CONSUME/INJECT + hospital dependency + subscribe + commit. |
T8 | SUB_TIME_IN_EJB_SUBSCRIBE_CALL | Time taken for the subscribe call in the EJB, includes RIB overhead surrounding the actual subscribe. |
T9 | SUB_TIME_IN_INJECT_CALL | Time taken by the INJECT call to the Java application. |
T10 | TAFR_TOTAL_MSGPROCESS_TIME | Time taken in the complete message tafring Process = TAFRing + hospital dependency + publish + RIB overhead. |
T11 | TAFR_TIME_IN_EJB_CALL | Time taken for the TAFR call in the EJB, includes RIB overhead surrounding the actual TAFRing. |
T12 | TAFR_TIME_IN_REAL_JMS_PUBLISH_EJB | Time taken by the TAFR to publish a message to the AQ JMS. |
Note: The following examples illustrate the process and concepts, but not test results. |
Order_pub_1 (Publisher)
TIMING_TYPE | COUNT | AVERAGE | TIME _SUM | MIN_TIME | MAX_TIME |
---|---|---|---|---|---|
PUB_B4_GETNXT_CALL | 100 | 0.03787 | 3.7904 | 0.036 | 0.07 |
PUB_TIME_IN_GETNXT_CALL | 100 | 0.06546 | 6.5528 | 0.061 | 0.254 |
PUB_TIME_IN_EJB_PUBLISH_CALL | 100 | 0.04192 | 4.1961 | 0.039 | 0.308 |
PUB_TOTAL_PUBLISH_TIME | 100 | 0.19675 | 19.6947 | 0.186 | 2.738 |
PUB_TIME_IN_REAL_JMS_PUBLISH_EJB | 100 | 0.02931 | 2.9341 | 0.027 | 0.292 |
OrderToOrderTafr_1 (TAFR)
TIMING_TYPE | COUNT | AVERAGE | TIME _SUM | MIN_TIME | MAX_TIME |
---|---|---|---|---|---|
TAFR_TOTAL_MSGPROCESS_TIME | 100 | 1.58708 | 158.708 | 1.296 | 4.135 |
TAFR_TIME_IN_EJB_CALL | 100 | 1.51371 | 151.371 | 1.23 | 3.24 |
TAFR_TIME_IN_REAL_JMS_PUBLISH_EJB | 100 | 1.1802 | 118.02 | 0.914 | 2.414 |
Order_sub_1
TIMING_TYPE | COUNT | AVERAGE | TIME _SUM | MIN_TIME | MAX_TIME |
---|---|---|---|---|---|
SUB_TIME_IN_CONSUME_CALL | 100 | 1.359 | 135.9 | 0.671 | 2.203 |
SUB_TOTAL_SUBSCRIBE_TIME | 100 | 1.93943 | 193.943 | 0.718 | 5.593 |
SUB_TIME_IN_EJB_SUBSCRIBE_CALL | 100 | 1.92386 | 192.386 | 0.687 | 5.593 |
In this example, to describe the serial processing through-put time to Publish 100 messages through the TAFR to Subscriber Consume:
Publisher (19.69 Sec) + TAFR (158.708 sec) + Subscriber (193.943 sec) = 372.341 seconds = Average 3.72 msg/sec
It is important to understand that the actual message through-put is not a calculation of the sum of the individual message times. Although the average time per message will remain fixed, messages are processed in parallel. So the total time to process n messages on a single channel will not be the serial sum of the individual messages.
Note: This is an illustration. The number of message needed to arrive at a calculation of through-put requires much higher counts, a broad spectrum of time, and system load. Other factors include average size of message. |
Every customer site has unique requirements and flows, so the ones to focus on will vary. However, there are ones that always make to the list.
ASN
Receipts (PO and Store)
Promotions
Stock Order (Allocation & Transfers)
Item Locations
Items
It is strongly recommended that during the deployment planning phase, the business requirements for these and others be gathered and analyzed. Some form of performance testing should be planned, even if only a characterization by measuring the actual flows during other test phases (for example, Integration Test).
The following diagram is a functional, detailed view of the Oracle Retail ASNin/ASNOut Flows.
The following diagram is logical view of the Oracle Retail Receipts Flow.
The following diagram is functional, detail view of the Oracle Retail Receipts Flow.
The Receipts message family is transactional data, and often a candidate for performance testing. Receiving consists of appointment and receipt messages that are published to RIB for RMS providing open to buy visibility. An appointment is information about the arrival of merchandise at a location. A receipt message informs RMS when merchandise arrives in a warehouse or store system.
The following diagram is a logical view of the Oracle Retail Stock Order Flow.
The following diagram is a functional, detail view of the Oracle Retail Stock Order Flow.
There are two distinct approaches to measuring RIB performance: using actual application end-points or using the RIB API simulators. Both are useful at different phases of deployment.
Keep in mind, that performance measuring is possible at any time in any phase, performance testing is more formal and requires planning, dedicated people and systems and test data. Building test data is difficult. Do not underestimate the complexity and this time consuming aspect of testing. To do testing with the applications involved, all of the data has to be consumable without errors.
There are tools available in RDMT to assist in this, as well as the audit feature of RIB. By enabling audit on an interface all messages are saved to a file in a form that can be played back by RDMT utilities.
The API Simulators (PL/SQL and Java EE) allow the focus to be on RIB infrastructure and is possible without resources outside of the RIB team. The value is limited to profiling the deployment architecture independent of the application API behavior and is much simpler in terms of data generation.
The performance measures of the end-to-end flow using the application's API is the only way to match performance against requirements since the majority of the time spent in the flow is in the application API. Customers do not distinguish a separation between RIB components and the application APIs.
The following illustrates the RIB Performance Test Harness.
Tools supplied to support both forms of tests are the RIB Test Harness, the API simulators, and the RDMT tools (timing utility, JMS Publish and EJB Publish).
This is a general process for measuring the flow end-to-end.
Prepare for the run. Use RIB Administration GUI to do the following.
Stop all adapters (PUB, SUB, TAFR).
Archive all logs so that the run has clean logs.
Enable timings logs (DEBUG) on all adapters.
Set all other adapter logs to INFO.
Determine how to generate the messages.
Using the Oracle Retail Application (for example, RMS to generate some orders).
Using RDMT EJB Publish (will use a portion of the PUB Adapter).
Using RDMT JMS Publish (will not use the PUB Adapter).
Start the appropriate adapters depending on the above decision.
Use RIB Administration GUI to start adapters (PUB, SUB, TAFR).
Generate the test messages.
Stop the adapters.
Analyze the data.
Use RDMT to run the Timing Analysis Utility on each adapter timing log. This creates a .csv file.
Upload the .csv files for display and further analysis using a tool such as Excel.
A channel is a solution approach to maintaining the previous RIB release concept of a Logical Channel.
Multi-channel applies to the logical partitioning of the flow of messages within the JMS topic. Multiple publishers and subscribers can simultaneously use the same JMS topic without any contention or interference, thus preserving publication message ordering within the logical channel.
Every adapter instance of a publisher, subscriber, or TAFR configured in RIB belongs to a logical channel for processing messages. Multi-channel adapters are multiple adapter instances for the same message family, each processing messages asynchronously and in parallel.
There are critical rules of behavior that must 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 simplify RIB configuration tasks that support a multi-channel message flow—the process has been integrated into the RIB application builder tools.
Multiple channels 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 Application Builder tools have checks and verification logic to prevent deployment of incomplete flows.
Use of multi-channels can 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. Multi-channeling capability for a message family is limited by the multi-channel support in the publishing performed by applications.
For example, the Inventory Adjustment (InvAdjust) message family is published by RWMS and subscribed to by RMS. Because RWMS supports only single-channel publishing, RMS must be set up for single-channel processing for the InvAdjust message family. All RWMS subscription APIs support multi-channel processing.
The following RMS publishing APIs support multi-channel processing:
ASNOUT Publication API
Allocations Publication API
Delivery Slot Publication API
Fulfill Order Confirmation Publication API
Item Location Publication API
Item Publication API
Merchandise Hierarchy Publishing API
Order Publication API
Receiver Unit Adjustment Publication API
RTV Request Publication API
Seed Object Publication API
Transfers Publication API
Work Orders in Publication API
Work Orders out Publication API
The following RMS publishing APIs do not support multi-channel processing:
Banner Publication API
Differentiator Groups Publication API
Differentiator ID Publication API
Partner Publication API
Seed Data Publication API
Store Publication API
Vendor Publication API
UDA Publication API
Warehouse Publication API
Each messaging RIB component involved in publishing or subscribing to a logical channel is distinctly identified by a JMS Message property known as ”Thread Value” 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 Thread Value property and this value as part of its JMS Durable Subscriber selector and each RIB publisher sets the ”Thread Value” 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 Thread Value of 1 (one). The naming convention and the RIB kernel code identify RIB adapters by adding the logical channel to the end of the adapter class name.
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
The following is the basic process for configuring a multi-channel flow.
Determine the family to configure as multi-channel.
Examine the rib-integration-flows.xml to identify all participants in the full flow.
In the rib-home modify the appropriate configuration files for each of the rib-<apps>.
rib-<app>-adapters.xml
rib-<app>-adapter-resources.properties
For PL/SQL Application edit the RIB_SETTINGS table.
Compile and deploy.
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.
Back up 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>
For RIB-RMS, complete the following steps.
Modify rib-rms-adapters.xml to add multiple channels.
Following is a portion 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>
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.
For RIB-TAFR, complete the following steps.
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" />
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
For RIB-SIM, complete the following steps.
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"/>
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.
For RIB-RWMS, complete the following steps.
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"/>
Modify rib-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.
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 5 for the Alloc Family.
To improve message publication throughput within the integration system, RIB provides multiple capabilities. The most efficient way to increase throughput of any system is to start working on the collection of data units instead of single data units. Using that philosophy, RIB provides capabilities to process the collection of multiple detail payloads in one transaction. To control the number of details (payload details) per payload header, the user must update the RIB_SETTING.MAX_DETAILS_TO_PUBLISH column in the PL/SQL retail applications database schema. This configuration allows users to control the size of the payload published within the RIB system.
Users also may aggregate messages in a transaction by bundling multiple payloads within a single message published to the JMS server, for example. Through message aggregation (<family>.maxNodesPerMessages), users can control the number of ribMessage nodes bundled into a single RibMessages message. Different families can have different nodes per message, so this property is qualified (prefixed) by the family name. This property allows control of the overall size of the RibMessages XML message.
RIB also allows users to optimize/minimize XA transaction overhead by allowing the system to commit multiple RibMessages to the JMS server in a single, two-phase XA commit. The number of messages committed to the JMS server in a single XA commit is controlled by the property named <family>.messagePerCommit. Different families may need different RibMessages per commit, so this property is qualified (prefixed) by the family name.
The configurable properties (<family>.maxNodesPerMessages and <family>.messagePerCommit) apply to each individual rib-<app>. To update the property and propagate the configuration to the app server, edit the corresponding rib-<app>.properties in rib-home and redeploy the updated rib-<app>.
Understand that the bigger the payload size, the bigger the memory requirement. A process (JVM) has limited amounts of operating system memory. If the size is too large, memory will run out, resulting in OutOfMemoryError.
If numerous ribMessageNodes are bundled into the same RibMessages message, a single failure in one of the ribMessages will roll back the full transaction, which will result in the following: The error hospital table will fill up and throughput will decrease by many factors, because now it has to go through the retry process.
The general best practice is to not prematurely optimize. Test with business data and only if the default values are not meeting business needs. Think about optimization by updating these properties.
To configure message aggregate, complete the following steps.
Edit the following file in rib-home:
rib-home/application-assembly-home/rib-<app>/rib-<app>.properties
Add the following properties:
<family>.maxNodesPerMessages=<your value>
<family>.MessagePerCommit=<your value>
Note: The value for <family> must be entered in all capital letters. For example, VENDOR. |
Using the app-builder tool compile/deploy the application.
rib-app-compiler.sh
rib-app-deployer.sh -deploy-rib-app-ear rib-<app>
Suppose there are 1,300 payload details waiting to be published for a family. Suppose the following configuration in RIB:
MAX_DETAILS_TO_PUBLISH=100
maxNodesPerMessagess=5
MessagePerCommit=2
The diagram below explains the message aggregation in play in the RIB system. All 1,300 payload details will be published in three RibMessages within only two XA transaction commits. Each of the first two RibMessages will have five ribMessage nodes, and each of the ribMessage nodes will have a payload with 100 payload details. The example shows 1,300 payload details; the third RibMessages XML will have only three ribMessage nodes, each with 100 payload details.
XA transaction 1 = (RibMessages1 + RibMessages2)
RibMessages1 = ribMessage1 + ribMessage2 + ribMessage3 + ribMessage4 + ribMessage5.
ribMessage1 = PayloadHeader + 100 * PayloadDetail
ribMessage2 = PayloadHeader + 100 * PayloadDetail
…..
ribMessage5 = PayloadHeader + 100 * PayloadDetail
RibMessages2 equivalent to RibMessages1
XA Transaction 2 = RibMessages3
RibMessages3 = ribMessage1 + ribMessage2 + ribMessage3
Total = (XA Transaction 1 + XA Transaction 2)
100*5 + 100*5 + 100*3 = 1300
The following is an illustration of RIB Message Aggregation.
This section explains the multiple hospital retry process.
RIB supports configuration of hospital retry adapters specific to message families. The family based adapters are configured to address performance issues when the error hospital gets very large--and a single retry adapter cannot handle the load.
Errors during processing result in messages in the error hospital. Reasons for errors include the following.
Incomplete or partial data from RMS: In this case, the messages are inserted into the error hospital with a reason code of PUB.
JMS related publication error conditions: (For example, the JMS server is down or not available due to network failures.) In this case, the messages are inserted into the error hospital with a reason code of JMS.
The subscriber application is not able to consume the message: In this case, the messages are inserted into the error hospital with a reason code of SUB.
By default, there are three kinds of hospital adapters, as listed below:
Sub retry adapter
JMS retry adapter
Pub retry adapter (RMS is the only application for which the Pub retry adapter is required.)
The sub retry adapter retries messages with a reason code of SUB only. Similarly, the JMS retry adapter and the Pub retry adapter retry messages with reason codes of JMS and PUB, respectively.
Note: For more information about the hospital retry mechanism, see "RIB Hospital Retry" in the Oracle Integration Bus Implementation Guide. |
Each message in the error hospital belongs to a particular message family. When the error hospital has a large number of messages from different families, the retry process becomes a performance bottleneck, as the default retry adapters retry the messages one by one (first in, first out), irrespective of message family.
To alleviate a bottleneck situation, retry adapters can be configured for a specific family and reason code. A family retry adapter can coexist with the default retry adapters. However, the default retry adapters will not retry those messages for which family retry adapters have been configured.
A family based retry adapter retries messages only for the family and reason code for which it is configured. For example, if a retry adapter is configured for the Order family and the SUB reason code, it retries only those messages from the Order family that failed with a reason code of SUB.
For each message family, a maximum of three family retry adapters can be configured—one for each reason code (PUB, SUB, and JMS).
The following is a process overview.
Determine the rib-<apps> where the family specific hospital retry adapter is to be configured.
Determine the family for which the retry adapter should be configured.
Determine the reason code (for example, PUB, SUB, or JMS) for the family retry adapter.
In the rib-home, modify the appropriate configuration files for the rib-<apps>:
rib-<app>-adapters.xml
rib-<app>-adapter-resources.properties
Compile and deploy.
Example:
To configure a family specific adapter for the Order family, where reason code = SUB and application = rib-rms, complete the following steps:
Backup the following files:
rib-home/application-assembly-home/rib-rms/rib-rms-adapters.xml
rib-home/application-assembly-home/rib-rms-resources.properties
Modify rib-rms-adapters.xml to add the family specific hospital retry adapter. The following is a portion of rib-rms-adapters.xml:
<hospitals> <timer-driven id="Order_familysubhosp_0" initialState="stopped" timeDelay="10" > <timer-task> <class name="com.retek.rib.j2ee.ErrorHospitalRetryTimerTask"/> </timer-task> </timer-driven/> <hospitals>
Modify rib-rms-adapter-resources.properties as follows:
Order_familysubhosp_0.name=Order SUB Hospital Retry
Order_familysubhosp_0.desc=Inject messages into JMS from Error Hospital
Note: Only one instance of family retry adapter can be configured per family and per reason code. |
Compile and deploy:
Using the RIB Installer or the RIB Application Builder command line tools, compile and deploy the new rib-<app>.ears.