3. Phase 3: Tuning
Now that you have your
performance metrics and have used PAL to help you identify bottlenecks
and potential areas of improvement, you are ready to do some tuning. You
have to identify the different adapters and hosts used by the solution.
This allows you to focus your attention on the components that require
the tuning. Before jumping into that, though, you need to understand how
to decipher those gathered metrics and ensure that your solution
follows coding best practices and the guidelines that eliminate
unnecessary extra configuration and tuning work.
4. What to Keep in Mind When Tuning
Out of the box, BizTalk
Server is optimized for high throughput by adaptively managing its rate
of polling received messages. This adaptive polling mechanism can cause
a maximum latency of 0.5 seconds by default. If the solution at hand
includes interactive scenarios where 0.5 seconds of latency is an issue,
that internal polling interval could be changed to a value as low as
0.1 seconds by modifying the MaxReceiveInterval value in the adm_ServiceClass table, which is part of the BizTalk Management Database (BizTalkMgmtDb).
Managing the incoming
throughput is one of the tuning options to handle bottlenecks whether
they are internal or external. Internal bottlenecks could be caused by
long execution times for a transform or a poorly designed orchestration,
resulting in extra persistence points. External bottlenecks are usually
caused by legacy backend systems or poorly designed services that
cannot keep up with the load.
To properly tune the server,
you need to know the expected throughput of the application, whether
there are external bottlenecks or not, and what the expected peak input
and its duration are. Knowing these, you need to analyze the gathered
performance counters accordingly and identify which counters are showing
problem areas. Table 1
highlights important performance counters and common causes for
undesirable performance values for these counters as well as some
troubleshooting options to rectify them.
Table 1. Main Bottleneck Analysis
Performance counter | Analysis | Options |
---|
Low % CPU Idle on BizTalk Server | Too many hosts running on the server.
Improper use of custom pipelines.
Custom components requiring optimization. | Isolate
the receive, process, and send functionality into different hosts and
run host instances on different servers within the BizTalk Server Group.
Move message transformation out of orchestrations to your ports to avoid the creation of new copies.
Move message filters to your ports and receive locations.
Optimize your schemas. Large schemas reduce performance.
Use distinguished fields in orchestrations rather than properties or XPath.
Use pass-through pipelines whenever possible. |
Low % CPU Idle on SQL Server | Check whether the DBA changed any of the default database settings set by the BizTalk installation.
Auto-Update Statistics and Max Degree of Parallelism are set to off and 1, respectively, on purpose. | Minimize the number persistence points in your orchestrations.
Use static methods instead of wrapping nonserializable components in atomic scopes.
Avoid using Parallel shapes, except when needed.
In a multi-Messagebox scenario, ensure that you have at least three
Messageboxes. The master Messagebox is doing all the routing to
secondary Messageboxes, which is CPU intensive. Whenever you are using
multiple Messageboxes, Microsoft's Distributed Transaction Coordinator
(DTC) is involved; therefore, you need to jump from one Messagebox to
three instead of only two to offset that overhead. |
Low % Disk Idle on SQL Server
High Avg. Disk Queue
Length on SQL Server | Check whether the tracking data-base and Messagebox are on the same disks.
Check whether the data and log files are on the same disks.
Check the log sizes.
Check the SQL Agents to ensure that the databases are being backed up.
Check whether the tracked messages' bodies are being archived. | Use a SAN.
Ensure that the tracking
and Messagebox databases are on different servers. If they are on the
same server, ensure that they are on different disks.
Ensure that the data and log files are not sharing the same disks.
Make sure the BizTalk agents are enabled on the server.
The agents copy tracking data from the Messagebox to the tracking
database. They also back up the databases and clean up the logs. |
|
|
If any of the scenarios outlined in Table 11-2
hold true, this means that the whole BizTalk platform is
underperforming, not just your solution, because these counters
influence the performance of the core BizTalk subsystems. Problems or
inefficiencies in one BizTalk solution could affect all other solutions
sharing the same environment with that problematic solution.
Other important metrics that
you can gather directly from your Messagebox are your spool table and
queue length. This gives you a complete understanding of what is
happening on the Messagebox level. The following is a set of code
snippets that you can use in a SQL script to gather this information;
another way to get this data is to create your SQL custom counters to
gather it. It is a good idea when doing any server analysis or
troubleshooting a problem to use a similar script to gather metrics on
your production environment before you start going through endless logs.
-- ---------------------------------------------------
-- Get the number of rows in the spool table (backlog)
-- ---------------------------------------------------
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SET DEADLOCK_PRIORITY LOW
SELECT COUNT(*) as Messages,
'Spooled Messages' as State
FROM [BizTalkMsgboxDb]..[spool] WITH (NOLOCK)
-- ---------------------------------------------------
-- ---------------------------------------------------------
-- Get the number of orchestrations and their state per host
-- ---------------------------------------------------------
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SET DEADLOCK_PRIORITY LOW
SELECT o.nvcName AS Orchestration, COUNT(*) as Count,
CASE i.nState
WHEN 1 THEN 'Ready To Run'
WHEN 2 THEN 'Active'
WHEN 4 THEN 'Suspended Resumable'
WHEN 8 THEN 'Dehydrated'
WHEN 16 THEN 'Completed With Discarded Messages'
WHEN 32 THEN 'Suspended Non-Resumable'
END as State
FROM [BizTalkMsgboxDb]..[Instances] AS i WITH (NOLOCK)
JOIN [BizTalkMgmtDb]..[bts_Orchestration] AS o
WITH (NOLOCK) ON i.uidServiceID = o.uidGUID
--WHERE dtCreated > '2004-08-24 00:00:00'
--AND dtCreated < '2004-08-24 13:30:00'
GROUP BY o.nvcName, i.nState
-- ---------------------------------------------------------
-- ----------------------------------------------------------
-- Get the number of Messages per host Q
-- IMPORTANT! Replace each instance of Q with the name of the
-- host that you are inspecting.
-- and the number of messages in the spool that are in that Q
-- ----------------------------------------------------------
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SET DEADLOCK_PRIORITY LOW
SELECT COUNT(*) as Messages, 'Suspended Non-Resumable' as State,
'FROM [BizTalkMsgBoxDb]..[WITH (NOLOCK)
--WHERE dtCreated > '2004-08-24 00:00:00'
--AND dtCreated < '2004-08-24 13:30:00'
SELECT COUNT(*) as Messages,
'Spooled Suspended Non-Resumable' as State,
'FROM [BizTalkMsgboxDb]..[spool] AS i WITH (NOLOCK
JOIN [BizTalkMsgboxDb]..[WITH (NOLOCK) ON i.uidMessageID = o.uidMessageID
--WHERE dtCreated > '2004-08-24 00:00:00'
--AND dtCreated < '2004-08-24 13:30:00'
SELECT COUNT(*) as Messages, 'Scheduled' as State,
'FROM [BizTalkMsgBoxDb]..[WITH (NOLOCK)
--WHERE dtCreated > '2004-08-24 00:00:00'
--AND dtCreated < '2004-08-24 13:30:00'
SELECT COUNT(*) as Count, 'Spooled Scheduled' as State,
'FROM [BizTalkMsgboxDb]..[spool] AS i WITH (NOLOCK)
JOIN [BizTalkMsgboxDb]..[AS o WITH (NOLOCK) ON i.uidMessageID = o.uidMessageID
--WHERE dtCreated > '2004-08-24 00:00:00'
--AND dtCreated < '2004-08-24 13:30:00'
SELECT COUNT(*) as Messages, 'Active' as State,
'FROM [BizTalkMsgBoxDb]..[WITH (NOLOCK)
--WHERE dtCreated > '2004-08-24 00:00:00'
--AND dtCreated < '2004-08-24 13:30:00'
SELECT COUNT(*) as Count, 'Spooled Active' as State,
'FROM [BizTalkMsgboxDb]..[spool] AS i WITH (NOLOCK)
JOIN [BizTalkMsgboxDb]..[WITH (NOLOCK) ON i.uidMessageID = o.uidMessageID
--WHERE dtCreated > '2004-08-24 00:00:00'
--AND dtCreated < '2004-08-24 13:30:00'
-- ----------------------------------------------------------