This chapter describes tips for tuning Oracle Service Bus performance. It contains the following sections:
Within a SOA framework, Oracle Service Bus (OSB) provides connectivity, routing, mediation, management and also some process orchestration capabilities. The design philosophy for OSB is to be a high performance and stateless (non-persistent state) intermediary between two or more applications. However, given the diversity in scale and functionality of SOA implementations, OSB applications are subject to large variety of usage patterns, message sizes and QOS requirements.
In most SOA deployments, OSB is part of a larger system where it plays the role of an intermediary between two or more applications (servers). A typical OSB configuration involves a client invoking an OSB proxy which may make one or more service callouts to intermediate back-end services and then route the request to the destination back end system before routing the response back to the client.
It is necessary, therefore, to understand that OSB is part of a larger system and the objective of tuning is the optimization of the overall system performance. This involves not only tuning OSB as a standalone application, but also using OSB to implement flow-control patterns such as throttling, request-buffering, caching, prioritization and parallelism.
For more information about Oracle Service Bus, see the Oracle Fusion Middleware Administrator's Guide for Oracle Service Bus.
Though the out-of-the-box monitoring sub-system has a very low overhead, and scales well to numerous services and multiple nodes in a cluster, when dealing with thousands of services or a large scale cluster deployment, being selective about enabling monitoring can help reduce network traffic. When a business or proxy service is created, monitoring is disabled by default for that particular service. For more information, see "Configuring Operational Settings for Proxy Services" or "Configuring Operational Settings for Business Services" in the Oracle Fusion Middleware Administrator's Guide for Oracle Service Bus.
To enable or disable monitoring of all services that have individually been enabled or disabled for monitoring, use the "Enable Monitoring" option on the Operations Global Settings page. For more information, see "Enabling Global Settings" in the Oracle Fusion Middleware Administrator's Guide for Oracle Service Bus.
Depending on your OSB usage and performance issues, you may consider tuning the following:
As with all other Oracle Fusion Middleware components, OSB performance can be impacted by JVM parameters. The two primary JVM tuning parameters to consider when optimizing OSB performance are heap size and garbage collection. For more information on tuning the JVM for performance, see Section 2.4, "Tuning Java Virtual Machines (JVMs)".
To optimize OSB, consider tuning the following WebLogic Server parameters:
For production environments, create a domain in "Production" mode to maximize performance. The parameter is:
To enable Weblogic server production mode through Weblogic Administration Console, see Oracle Fusion Middleware Understanding Domain Configuration for Oracle WebLogic Server.
For OSB performance testing and production environments, consider using the lowest acceptable logging level, such as "ERROR" or "WARNING" whenever possible. For more information, see Section 2.10, "Setting Logging Levels"
To optimize OSB perfomance, consider turning off the HTTP access logging. For more information, see Section 18.104.22.168, "Access Logging".
Ensure that the right persistence level is set for the Java Message Service (JMS) destinations. Consider the following scenarios:
For non-persistent JMS scenarios:
Explicitly turn off persistence at the JMS server level by un-checking the "Store Enabled" flag from the Advanced section of the General tab for the JMS server on the WebLogic Server console. It is also possible to override the persistence mode at the JMS destination level.
For persistent JMS scenarios:
There are two choices: file store and JDBC store. Typically operations on a File Store perform better than JDBC store. If there are multiple JMS servers involved, create each store on a separate disk to lower I/O contention.
For more information on JMS Server Tunings, see "Tuning WebLogic JMS" in the Oracle Fusion Middleware Performance and Tuning for Oracle WebLogic Server.
You can tune the number of connection requests that a WebLogic Server instance will accept before refusing additional requests. The Accept Backlog parameter specifies how many Transmission Control Protocol (TCP) connections can be buffered in a wait queue. This fixed-size queue is populated with requests for connections that the TCP stack has received, but the application has not accepted yet. This parameter should be tuned when dealing a large number of concurrent clients. For more information, see "Tuning Connection Backlog Buffering" in Oracle Fusion Middleware Performance and Tuning for Oracle WebLogic Server.
This section discusses the following Oracle Service Bus operational settings:
Oracle Service Bus has the option to trace messages without having to shutdown the server. This is an extremely useful feature both in a development and production environment for debugging, diagnosing and troubleshooting problems involving message flows in one or more proxy services.
Tracing is disabled by default but can be enabled on a per service basis. When tracing is enabled, the entire message context is also printed including headers and message body. It is important to realize its impact for large message sizes and high throughput scenarios.
For more information, see "How to Enable or Disable Tracing" in the Oracle Fusion Middleware Administrator's Guide for Oracle Service Bus.
OSB caches proxy service runtime meta-data using a two-level cache with static and dynamic sections. The cache introduces a performance tradeoff between memory consumption and compilation cost. Note that caching proxy services may help throughput but could impact memory usage.
The static section is an upper-bound Least Recently Used (LRU) cache that is never garbage collected. When a proxy service is bumped from the static section, it is demoted to the dynamic section where the cache can be garbage collected when there is memory pressure.
The number of proxy services in the static portion of the cache can be tuned by setting its size using the system property
com.bea.wli.sb.pipeline.RouterRuntimeCache.size. The default value is 100. This can be increased to a desired value provided there is sufficient memory for runtime data processing for large number of proxy services.
This property value can be set in the setDomainEnv.sh file as an extra java argument as follows:
To preload the router runtime cache with the compiled runtime of proxy services, set the system property,
Enabling this property may improve performance by decreasing the time it takes to make the initial calls to the proxy server. It can also preload the cache when a configuration session is committed.
If the number of proxy services exceeds 100, then the
com.bea.wli.sb.pipeline.RouterRuntimeCache.sizeproperty should be used to set the appropriate cache size as the cache size is finite.
The OSB system property
com.bea.wli.sb.pipeline.initializeRouterCache initializes the RouterRuntimeCache for proxy services at server startup. Setting this property to
true processes the first request to the proxy service faster since the runtime metadata model required for proxy service execution is already built at server startup. It is important to note, however, that this property can lead to longer server startup times due to the proxy service model initialization that is done.
To initialize the RouterRuntimeCache at server startup, set the system property as follows:
After you have performed the modifications recommended in the previous section, you can make additional changes that are specific to your deployment. Consider carefully whether the recommendations in this section are appropriate for your environment.
Latency and throughput of poller-based transports depends on the frequency with which a source is polled and the number of files and messages read per polling sweep.
The following are the main transport configurations to tune:
Consider using a smaller polling interval for high throughput scenarios where the message size is not very large and the CPU is not saturated. The primary polling interval defaults are listed below with links to additional information:
|Polling Intervals||Default Interval||Additional Information|
|File Transport||60 seconds||"File Transport Configuration Page" in the Oracle Fusion Middleware Administrator's Guide for Oracle Service Bus|
|FTP Transports||60 seconds||" FTP Transport Configuration Page" in the Oracle Fusion Middleware Administrator's Guide for Oracle Service Bus|
|MQ Transport||1000 milliseconds||"MQ Transport Configuration Page" in the Oracle Fusion Middleware Administrator's Guide for Oracle Service Bus|
|SFTP Transport||60 seconds||"SFTP Transport Configuration Page" in the Oracle Fusion Middleware Administrator's Guide for Oracle Service Bus|
|JCA Transport||60 seconds||"JCA Transport Configuration Page" in the Oracle Fusion Middleware Administrator's Guide for Oracle Service Bus|
The read limit determines the number of files or messages that are read per polling sweep. This defaults to 10 for the File and FTP transports. It can be set to 0 to specify no limit. Set this value to the desired concurrency. For more information, see " File Transport Configuration Page" in the Oracle Fusion Middleware Administrator's Guide for Oracle Service Bus.
Note:Setting the Read Limit to a high value and the Polling Interval to a small value may result in a large number of messages being simultaneously read into memory. This can lead to an OOM (out-of-memory error) if the message size is large.
Consider the following design configurations for proxy applications based on your OSB usage and use case scenarios:
Avoid creating many OSB context variables that are used just once within another XQuery
Context variables created using an Assign action are converted to XmlBeans and then reverted to the native XQuery format for the next XQuery. Multiple "Assign" actions can be collapsed into a single Assign action using a FLWOR expression. Intermediate values can be created using "let" statements. Avoiding redundant context variable creation eliminates overheads associated with internal data format conversions. This benefit has to be balanced against visibility of the code and reuse of the variables.
Transforming contents of a context variable such as
Use a Replace action to complete the transformation in a single step. If the entire content of $body is to be replaced, leave the XPath field blank and select "Replace node contents". This is faster than pointing to the child node of $body (e.g. $body/Order) and selecting "Replace entire node". Leaving the XPath field blank eliminates an extra XQuery evaluation.
$body/* to represent the contents of
$body as an input to a Transformation (XQuery / XSLT) resource.
OSB treats "
$body/*" as a special XPath that can be evaluated without invoking the XQuery engine. This is faster than specifying an absolute path pointing to the child of
$body. A general XPath like "
$body/Order" must be evaluated by the XQuery engine before the primary transformation resource is executed.
Enable Streaming for pure Content-Based Routing scenarios.
Read-only scenarios such as Content-Based Routing can derive better performance from enabling streaming. OSB leverages the partial parsing capabilities of the XQuery engine when streaming is used in conjunction with indexed XPaths. Thus, the payload is parsed and processed only to the field referred to in the XPath. Other than partial parsing, an additional benefit for read-only scenarios is that streaming eliminates the overhead associated with parsing and serialization of XmlBeans.
The gains from streaming can be negated if the payload is accessed a large number of times for reading multiple fields. If all fields read are located in a single subsection of the XML document, a hybrid approach provides the best performance. See Section 21.4.3, "Design Considerations for XQuery Tuning" for additional details.
The output of a transformation is stored in a compressed buffer format either in memory or on disk. Therefore, streaming should be avoided when running out of memory is not a concern.
Set the appropriate QOS level and transaction settings.
Do not set XA or Exactly-Once unless the reliability level required is once and only once and its possible to use the setting (it is not possible if the client is a HTTP client). If OSB initiates a transaction, it is possible to replace XA with LLR to achieve the same level of reliability.
OSB can invoke a back end HTTP service asynchronously if the QOS is "Best- Effort". Asynchronous invocation allows OSB to scale better with long running back-end services. It also allows Publish over HTTP to be truly fire-and-forget.
Disable or delete all log actions.
Log actions add an I/O overhead. Logging also involves an XQuery evaluation which can be expensive. Writing to a single device (resource or directory) can also result in lock contentions.
OSB uses XQuery and XPath extensively for various actions like Assign, Replace, and Routing Table. The following XML structure ($body) is used to explain XQuery and XPath tuning concepts:
<soap-env:Body> <Order> <CtrlArea> <CustName>Mary</CustName> </CtrlArea> <ItemList> <Item name="ACE_Car" >20000 </Item> <Item name=" Ext_Warranty" >1500</Item> …. a large number of items </ItemList> <Summary> <Total>70000</Total> <Status>Shipped</Status> <Shipping>My Shipping Firm </Shipping> </Summary> </Order> </soap-env:Body>
Avoid the use of double front slashes ("//") in XPaths.
$body//CustName while returning the same value as $body/Order/CtrlArea/CustName will perform a lot worse than the latter expression. "//" implies all occurrences of a node irrespective of the location in an XML tree. Thus, the entire depth and breadth of the XML tree has to be searched for the pattern specified after a "//". Use "//" only if the exact location of a node is not known at design time.
Index XPaths where applicable.
An XPath can be indexed by simply adding "" after each node of the path. XQuery is a declarative language and an XPath can return more than one node; it can return an array of nodes.
$body/Order/CtrlArea/CustName implies returning all instances
$body and all instances of
Order. Therefore, the entire document has to be read in order to correctly process the above XPath. If you know that there is a single instance of
$body and a single instance of
Order, we could rewrite the above XPath as
The second XPath implies returning the first instances of the child nodes. Thus, only the top part of the document needs to be processed by the XQuery engine resulting in better performance. Indexing is key to processing only what is needed.
Note:Indexing should not be used when the expected return value is an array of nodes. For example,
$body/Order/ItemList/Itemreturns all "Item" nodes, but
$body/Order/ItemList/Itemonly returns the first item node. Another example is an XPath used to split a document in a "for" action.
Extract frequently used parts of a large XML document as intermediate variables within a FLWOR expression
An intermediate variable can be used to store the common context for multiple values. Sample XPaths with common context:
The above XPaths can be changed to use an intermediate variable:
let $summary := $body/Order/Summary $summary/Total, $ summary/Status, $summary/Shipping
Using intermediate variables consumes more memory but reduces redundant XPath processing.
Using a Hybrid Approach for read-only scenarios with Streaming
The gains from streaming can be negated if the payload is accessed a large number of times for reading multiple fields. If all fields read are located in a single subsection of the XML document, a hybrid approach provides the best performance. The hybrid approach includes enabling streaming at the proxy level and Assigning the relevant subsection to a context variable, The individual fields can then be accessed from this context variable.
The fields "Total" and "Status" can be retrieved using three
Assign "$body/Order/Summary" to "foo" Assign "$foo/Total" to "total" Assign "$foo/Status" to "total"