The threading model that you use when you develop an Application Integration Component (AIC) greatly affects the performance of the component. The performance of the AIC affects the overall throughput of the BizTalk Messaging engine. This applies to AICs that use either the
IPipelineComponent or the
IBTSAppIntegration COM Interface.
COM terminology
You can use COM objects in multiple threads of a process.
The terms
Single-threaded Apartment (STA) and
Multi-threaded Apartment (MTA) are used to create a conceptual framework to describe the following:
- the relationship between objects and threads.
- the concurrency relationships among objects.
- the means by which method calls are delivered to an object.
- the rules for passing interface pointers among threads.
Components and their clients support the following three ThreadingModel settings:
- Multi-threaded Apartment model (MTA): One or more threads execute in the MTA. Any object in the MTA may be serviced by any thread in the MTA. Access to the object is not limited to the thread that created the object.
Because multiple simultaneous clients may call objects more or less simultaneously (simultaneously on multi-processor systems), objects must synchronize their internal state by themselves. Interfaces are not marshaled between threads. Some earlier Microsoft information and documentation refers to this model as the free-threaded model. - Single-threaded Apartment model (STA): Only one thread can execute in any given STA (there may be multiple STAs in the process). The object or the objects that run inside a given STA can only be serviced by the thread that created or instantiated the STA. All calls to and from obects in an STA are marshaled when the caller or callee is outside the same STA. A variant case of the single-threaded apartment model is called the Single-threaded model. In this case, all objects that are created from any STA-based class execute in the same STA. Therefore, access to any of these objects is serialized into the one thread that services this lone STA.
Some earlier Microsoft information and documentation refers to the STA model as the apartment model.
You can use both the STA model and the MTA model in the same process. This is sometimes named a
mixed-model process.
Select a threading model
The BizTalk Server Messaging engine is multi-threaded; the engine launchs AICs on multiple threads when processing documents. To fully use the benefits of the multi-threaded architecture, develop the AICs to support their hosting in an MTA.
The
BizTalk Server Adapter Developer's Guide strongly recommends that for high performance scenarios, AICs should support the MTA hosting model. This white paper states the following:
"This should be understood to mean that Visual Basic 6 should not be used to develop components that are required to meet the needs of performance intensive scenarios. By default and design, Visual Basic 6 generates components that execute in a single threaded apartment (STA) thus causing the BizTalk engine to marshal parameters from a multithreaded apartment into the single threaded apartment and back. Visual C++ and other tools that are capable of generating MTA components should be used to develop high performance components."
For more information about poor performance of Visual Basic AICs, click the following article number to view the article in the Microsoft Knowledge Base:
291670
Slow performance of application integration components that are written in Visual Basic
The BizTalk Server Messaging engine has a dedicated number of worker threads that poll the BizTalk Work Item queue for documents to process. You can configure the number of worker threads that the BizTalk Server Messaging engine uses by setting the Server property
Maximum number of worker threads allowed. If, as a result of processing a document, an AIC must be called, then the component must be instantiated and the appropriate method must be called.
Free threaded AICs
When the AIC is free threaded, the component is instantiated within the MTA of the BizTalk Messaging Service (Mscis.exe). The methods on the AIC can now be called directly with no marshalling, which results in very high performance. BizTalk Server Messaging does not share instances of AICs across its threads. Therefore, BizTalk does not gain access to a component multiple times concurrently. This simplifies the development of free threaded components.
Apartment threaded AICs
When an AIC is apartment threaded, the component must be hosted within an STA apartment. Therefore, when the worker thread (which is running in the MTA) is required to instantiate an apartment threaded component within the same process, the Component Object Model (COM) infrastructure instantiates that component within the Host STA. There is only one Host STA per process. The Host STA is designed specifically to house objects from STA-based classes when their creator has a ThreadingModel of Free.
The BizTalk Server Messaging process (Mscis.exe) has only one STA apartment that hosts all the apartment threaded AICs. The worker threads gain access to the STA hosted components through a proxy interface. The Host STA runs on a single thread. To prevent method calls being re-entrant, the Host STA uses an internal message loop to queue up each method call. A single thread takes messages off this queue (such as methods calls), and then makes the call to the component on the same thread. Because there is only one Host STA that hosts all apartment threaded AICs, all method calls to these components are queued behind each other.
In this example, the following are true:
- Worker thread 1 has called ProcessMessage on component A.
- Worker thread 2 has called ProcessMessage on component B.
- Worker thread 3 has called ProcessMessage on another instance of component A.
These calls are processed sequentially in the Host STA. The call to component B will not complete until the preceding call to ProcessMessage in Component A is completed. If the methods calls block for any period of time, this adversely affects performance.
Increase AIC performance by using COM+
Both the
BizTalk Server Adapter Developer's Guide
and the Microsoft Knowledge Base article
291670
describe some adverse affects of apartment threaded AICs that are developed in Visual Basic 6.0. By using Microsoft COM+, you can increase the performance of these components in some cases. When an AIC is installed in a COM+ server application, it runs in a separate process (Dllhost.exe) that is managed by COM+. The performance increase is achieved because COM+ creates and manages a pool of STA threads.
The performance advantages of this are the following:
- Each component you deploy in a COM+ application is isolated from other COM+ applications. For example, if you deploy AIC A and AIC B in separate COM+ applications, method calls to each component are not serialized behind each other.
- Each COM+ application maintains a thread pool of STA hosts instead of only a single STA host.
The following table compares the performance of apartment components and free threaded components for deployments in and out of COM+. For the test, 500 documents were submitted for processing. This caused an AIC to be called that writes to the Windows Event log, and that blocks for two seconds. The test was conducted on a single processor Pentium III 800 server that had 512 megabytes (MB) of RAM and was configured with 12 worker threads.
The test results show only the broad relative speed difference between these approaches. These results are not a definitive performance evaluation. For example, when you deploy apartment components and free threaded components on multiple processor systems, the profile of the performance is different. Most noticably, the free threaded components show an additional increase.
AIC performance comparison
+--------------------------------------------------------------+
| | | | | Relative |
| Model | Host | Time | Docs/sec | speed |
+--------------------------------------------------------------+
| Apartment | MSCIS.exe | 16 min | 0.50 | 1.0x |
| (Visual Basic) | | 37 sec | | |
+--------------------------------------------------------------+
| Apartment | COM+ Library | 2 min | 3.93 | 7.8x |
| (Visual Basic) | Application | 7 sec | | |
+--------------------------------------------------------------+
| Apartment | COM+ Server | 1 min | 4.35 | 8.7x |
| (Visual Basic) | Application | 55 sec | | |
+--------------------------------------------------------------+
| Free Threaded | MSCIS.exe | 1min | 5.81 | 11.6x |
| (C++ ATL) | | 26 sec | | |
+--------------------------------------------------------------+
| Free Threaded | COM+ Library | 1 min | 5.88 | 11.7x |
| (C++ ATL) | Application | 25 sec | | |
+--------------------------------------------------------------+
| Free Threaded | COM+ Server | 1 min | 5.81 | 11.6x |
| (C++ ATL) | Application | 26 sec | | |
+--------------------------------------------------------------+
Limitations of apartment threaded AICs that make long running method calls
When you put an apartment threaded AIC into COM+, the performance of the AIC might increase. However, this increase can occur only if the AIC does not make any long running (or
blocking) method calls. A call is considered blocking if it takes a long or indeterminate time to return, for example, calls to the backend, network calls that use remote procedure call (RPC), or sockets.
If your apartments threaded AICs must make long running method calls, you must develop these AICs as free threaded components. Do not use Visual Basic 6.0 to develop these components.
For more information, click the following article number to view the article in the Microsoft Knowledge Base:
291837
Do not make blocking calls from an STA component
If your AICs must make long running method calls, you must develop them as free threading components by using Visual C++ ATL or by using Visual Studio .NET.
Note BizTalk Server 2000 does not support Application Integration Components that you write in Visual Studio .NET.
For more information, click the following article number to view the article in the Microsoft Knowledge Base:
832165
BizTalk Server 2000 does not support components that are written in Visual Studio .NET
Apartment Threaded Components Do Not Scale
The following describes why apartment threaded components that make long running method calls do not scale. This description is taken from the following Microsoft Web site:
In COM+, each server application maintains two separate thread pools. One thread pool services STA objects while the other thread pool services free threaded components (and has no upper limit on the number of threads).
The algorithm that is used to manage the thread pool for Windows 2000-based configured STA components is more complex than the algorithm that is used for MTS under Windows NT 4.0.
The COM+ STA thread pool has the following attributes:
- The pool size has an initial size of 7 + n threads, where n is the number of processors.
- The maximum size of this pool is 10 * n threads.
- Work items are queued on specific threads, so that when each thread is bound to five activities (in total 5 * (7 + n) work items), a new thread is created, up to the maximum pool size that is permitted.
- When the maximum pool size is reached, any additional work items are queued on the existing threads. Therefore, each thread can have more that five activities on it.
- If the number of threads in the pool is greater than the minimum (7 + n), and threads become idle for some time, these idle threads are terminated. The pool size does not decrease below the minimum size.
For example, on a single CPU system, the STA pool grows from eight to the maximum of 10 STA threads. Unlike MTS, COM+ binds up to five activities to a thread. Because COM+ binds multiple activities to a thread, the first activity to be serviced can take as long as the summation of all pending activities if it makes OOA (Out-Of-Apartment) calls. The following is an example of how this process works:
- You have five activities that are bound to a pooled COM+ STA thread. Activity 1 gets the thread and its method starts to run.
- During the method call, Activity 1 makes an OOA call. The COM channel enters the thread's message loop and continues to pump messages while the RPC sending thread makes the actual blocking call. Activity 2 is serviced while Activity 1 waits for the method call to return.
- The problem is that Activity 1 cannot gain control of the STA thread again until Activity 2 completes its work. If Activity 2 also makes an OOA call, and then Activity 3 gets the STA thread, the process can continue all the way to Activity 5 (if all these activities make OOA calls).
- Activity 1 must wait for Activity 2 to complete, which must wait for 3 to complete, which must wait for 4 to complete, and so on. The end result is that if these calls are long running, because COM+ queues up to five activities per thread, the time that is required for first activity's method to run is the total of its own time to run plus the time required for the other four activities to run.
Under MTS, long running calls did not cause as much of a problem until the thread pool became exhausted. Before that point, none of the threads would prevent other callers from being serviced, nor would they have been prevented from completing themselves. But with 100 threads, for applications written properly with short duration method calls, the context switching can slow performance.
To minimize context switching, the COM+ STA thread pool is optimized for short-running method calls with far fewer threads. It is recommended that you avoid long running method calls. Unlike client-server computing, the paradigm of
n-tier processing is to "get in and get out" as quickly as possible. Because of the size and activity binding of the MTS STA thread pool, you could mask this problem in your architecture. Under COM+, the problem may be exposed.
NOTE: You can configure the COM+ STA thread pool to run as the MTS thread pool does by setting 100 threads and one activity per thread. You do this through the
EmulateMTSBehavior registry key. This is not recommended because the COM+ thread pool mechanism is designed to improve performance, and there are valid reasons for using its algorithm. For more information, see the following Microsoft Web site:
COM+ process isolation
COM+ provides performance benefits to apartment threaded components. However, COM+ can also provide process isolation of the AICs from the BizTalk Messaging engine itself. You can achieve ultimate performance by deploying the free threaded component in-process to the BizTalk messaging engine, but you lose process isolation. A failure in the in-process AIC could lead to a failure in the BizTalk Messaging engine.
Therefore, it is recommended that you deploy BizTalk AICs in COM+ as Server applications, unless both of the following are true:
- You must have ultimate performance.
- You have comprehensively tested the AICs.
This provides process isolation. You can deploy AICs as COM+ Server applications to get a finer degree of control. This permits you to shut down an individual COM+ application (or package in MTS terminology) if a problem occurs with a particular component.
If the components are apartment threaded, decide carefully how many COM+ applications you use because the application has a single MTA thread pool and the more components that you deploy in the application, the greater the load on the thread pool. Also, each COM+ application loads a new process, which increases the server load.
Free threaded components offer greater scalability because you do not have to balance thread pool load and server load. You can deploy free threaded components into a COM+ application without any effect on scalability.
Increase performance through COM+ object pooling
You can also increase performance of AICs by using COM+ object pooling. Object Pooling can improve performance by eliminating activation overhead. The COM+ Object Pool creates the component on an MTA thread. The following is a list of requirements for Object Pooling:
- Objects must be marked with TM=free, TM=both, or TM=neutral. You cannot pool objects that are marked Apartment (you cannot pool Visual Basic components because they run in STA).
- Objects must be aggregatable.
- Objects must implement IObjectControl, which permits COM+ Services to manage the object.
- Objects must not be Apartment Agile by aggregating FTM (Free Thread).
- You must prepare objects to be called on any thread. Mark the object with synchronization = required, which verifies that one thread at a time will have access to the object.
- Objects must not hold any context-dependent state across activations.
- Objects must not aggregate any other pooled object.
COM+ uses the concept of an outer container object that pools the inner objects in itself. Unfortunately, not every development environment can create poolable objects. You cannot pool Visual Basic 6.0 objects because they cannot be aggregated by an outer wrapper component.
Therefore, to write poolable objects, you must use Visual C++ and the Active Template Library or Visual Studio .NET. If you write your components to support aggregation, they are automatically pooled.
Note BizTalk Server 2000 does not support Application Integration Components that you write in Visual Studio .NET.