Table of Contents Isolate. Isolate. Isolate.ThrottlingMessages/Variables scopePersistence PointsMapDistinguished Field vs. Promoted PropertyExternal ComponentsLatencyTracking – Orchestration EventsThread Pool SizeLong-Running Singleton OrchestrationsUsing XLANGMessage and XLANGPartAcknowledgmentsSee Also
Fine tuning performance is difficult and time-consuming. It will be even harder after the system is put into production. So our first advice is to make sure you perform performance testing before going for production. The performance testing should cover the foreseen peak load as well as the average load.
Here are general guidelines in tuning and troubleshooting Orchestration performance:
The Receive Shape, Listen Branch, and Delay Shape are conditional persistence points. They will dehydrate if there is a wait for a subscription that takes longer than 2*MaxThreshold. In BizTalk 2010, the Maximum Threshold value is configured in the Settings Dashboard. In BizTalk 2009 and earlier, these values are configured in BTSNTSvc.exe.config or BTSNTSvc64.exe.config file.
Each persistence point requires your Orchestration instance and the associated data to be serialized to the database. This can impact performance if you have a large number of persistence points or if there is a large amount of data to be serialized. During design time, you can use the persistence points listed above as a guide to adjust your workflow. During runtime, the dehydration and persistence counters in Performance Monitor under the XLANG/s Orchestration performance object can be used to determine if excessive persistence may be a factor in your performance issue.
To prevent persistence, enclose a potential persistence point within an Atomic Scope. The Orchestration Engine won’t persist until it reaches the end of the transaction. But, be careful when you do this! It does keep the Orchestration instance from persisting but also forces the Orchestration instance to remain in memory instead of dehydrating. It is possible to run out of system resources if you have a large number of active Orchestration instances.
Transformations are more efficient when they are executed from a send or receive port. There are scenarios where it makes sense to have a map in an Orchestration. For example, you can execute a transformation dynamically within an Expression Shape. Maps in Orchestration can also accept multiple inputs. In general, unless there is an absolute requirement to use a map in an Orchestration, don't do it.
When you promote a property, consider how you’ll be using it. If you will only access the data within an Orchestration, promote the property as a Distinguished Field only. If you plan to use a field outside of an orchestration, like as a filter for a Send Port subscription, use it as a Promoted Property. Promoted Property Fields can be used for routing but are also more expensive.
It is normal and expected for Orchestrations to use external assemblies within an Expression Shape. When you call a method from an external assembly or unmanaged code, be aware that the Orchestration Engine has little control over what happens within the external code. If this external code fails, your Orchestration design needs to handle the exception. If the method call does not return in a timely manner, the Orchestration Engine will continue to wait on it. Do not assume or expect that the Orchestration Engine will "timeout" or terminate the external component. If you want a timeout, build it into the method you are calling. With any custom code, you should implement tracing and/or debugging information. We have seen many cases where an Orchestration instance fails within the custom code. Since there was no tracing within the component, a lot of time was spent isolating the failure. Once the problem was isolated to the custom component, the issue still needed to be resolved by the original developer since we didn’t have any knowledge of the component. It is more efficient for you if we can quickly determine what is failing and who should be engaged to fix the issue.
If a message is received after an orchestration has been idle, there may be a delay with the orchestration. This may be caused by an application domain unloading within the BizTalk host process. If an AppDomain is shut down, the next message must wait for the Orchestration to reload. This can be a noticeable wait time. To prevent this in a low latency scenario, add the SecondsIdleBeforeShutdown property to the BizTalk config file (BTSNTSvc.exe.config or BTSNTSvc64.exe.config) file:
<
DefaultSpec
SecondsIdleBeforeShutdown
=
"-1"
SecondsEmptyBeforeShutdown
"1800"
>
SecondsEmptyBeforeShutdown is the number of seconds that an app domain is empty (does not contain any orchestration instances) before being unloaded. Setting it to -1 to signal that an AppDomain should never unload, even when empty.
Document tracking can impact performance throughout BizTalk, not just Orchestration. Orchestration Event Tracking is enabled by default. This can be helpful during development, testing and troubleshooting with Orchestration Debugger. In Production, these tracking events should be disabled. When enabled, these events are written to the TrackingData_x_x tables in the BizTalkMsgBoxDb database and then moved to the dta_DebugTrace table in the BizTalkDTADb database by the Tracking host. If the TrackingData_x_x tables (BizTalkMsgBoxDb database) and/or the dta_DebugTrace table (BizTalkDTADb database) get too large*, performance will be impacted.
If the Tracking host cannot move data efficiently into the BizTalkDTADB database, data will accumulate in the BizTalkMsgBoxDb database. A large BizTalkMsgBoxDb database can cause all hosts to slow down and eventually lead to throttling.
The Orchestration Engine and many of the BizTalk Adapters use worker threads from the managed thread pool. If there is a large number of orchestration instances that must be active, it's very common to increase the thread pool size. If you suspect thread starvation, monitor the Running Orchestrations Performance Monitor counter under the XLANG/s Orchestrations object. The number of running orchestration instances may increase and then remain constant. You can usually detect this by monitoring the Running Orchestrations performance counter under the XLANG/s Orchestrations performance object. You may notice that the number of running Orchestrations increases and then remains constant when it reaches the thread pool limit. In BizTalk 2010, the thread settings can be modified in the Settings Dashboard (http://go.microsoft.com/fwlink/?LinkId=239982). In BizTalk 2009 and earlier, add the CLR Hosting registry key (http://technet.microsoft.com/library/dd722826(BTS.10).aspx). Before you suspect thread pool as an issue, confirm there is no throttling and that your system is not already under stress.
Singleton orchestrations usually involve correlated receives within a loop. This design pattern is often used for batching, maintaining ordered processing or throttling downstream flow. Using a singleton is fine normally doesn’t raise a performance concern. If there is a looping condition that keeps an orchestration alive for days or weeks, you may notice gradual performance degradation. The reason? As an orchestration loop, it is possible for different objects to accumulate and eventually impact performance. During development, make sure all objects you create are cleaned up when no longer needed. Also, add logic to limit the lifespan of your singleton orchestration. The mechanism would depend on your business scenario. For example, terminate an orchestration instance only when it is idle. a) Add a Listen Branch into the loop. b) On one branch, you receive the correlated message as before. c) On the other branch, use a Delay Shape and specify the timer value. d) Add an Expression shape with logic to exit the loop. The concept is simple. When messages are flowing in, the execution path will stay on the receiving side of the Listen Branch. When message delivery stops, the timer value in the Delay Shape will exceed. Then, the execution path moves to the delay branch. After the Delay shape, set a Boolean variable in an Expression Shape to exit the loop. The orchestration instance completes and the next message delivered to the orchestration engine starts a new instance of the orchestration.
When passing XLANGMessage and XLANGPart to a custom component, the custom component generally needs to take care of its lifetime requirement and dispose of it promptly. Messages Represented as XLANGMessage (http://go.microsoft.com/fwlink/?LinkId=239985) has the details.
This Wiki post was taken from the following blog posts and updated to reflect BizTalk 2010: