Production Configuration Settings
Applies to: Windows Communication Foundation
Published: June 2011
Author: Robert Dizon
This topic contains the following sections.
- Optimal Settings for Performance and Scalability
- Conclusion
- Additional Resources
Optimal Settings for Performance and Scalability
This section is a compilation of optimal configuration settings and fixes for performance and scalability issues. Apply and test these fixes during development, before you use them in production. You can consider these groups of related configuration settings as a reference that you can use to fine-tune WCF solutions that are deployed in enterprise-level integration scenarios.
The configuration settings are grouped by hop. Refer to the three-tier architecture illustration to identify where the hops are in the overall scenario.
From Hop 1 – WCF Client or User-facing Web Application (Node 1) and IIS hosting (Node 2):
Microsoft provides extensive configuration guidelines for WCF client and IIS application server. See the following links:
For detailed information on client side optimization see the Microsoft Support site at https://support.microsoft.com/kb/821268.
For additional information about optimizing IIS 6.0, see "Optimizing IIS 6.0 Performance" on TechNet at https://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/e621190d-1015-40c2-a5ec-0dcb32c98286.mspx?mfr=true.
For additional information about optimizing IIS 7.0, see "Optimizing IIS 7.0 Performance" on TechNet at https://technet.microsoft.com/en-us/library/cc770381(WS.10).aspx.
From Hop 2 (Node 3) – WCF Service Configuration Settings:
Microsoft provides extensive configuration guidelines for WCF performance and scalability. See the following links:
"Configuring Windows Communication Foundation Applications" on MSDN at https://msdn.microsoft.com/en-us/library/ms730120.aspx
"Windows Communication Foundation Configuration Schema" on MSDN at https://msdn.microsoft.com/en-us/library/ms731734.aspx
From Hop 3 (Node 4) – Data Access or WCF Optimization Code:
There is a useful discussion with procedures on optimizing the data access layer at this link: http://www.linkedin.com/answers/technology/software-development/TCH_SFT/416855-13606449
The following section includes more possible code fixes to help you to optimize performance and scalability. However, these fixes are more time-consuming than the ones in the previous section. They may require more development time or that you refactor your existing code. Use these fixes only if you have tried all the recommended configuration settings and found none of them to work.
Recommended Code Modifications:
Use asynchronous client-side invocations. For more information, see "Summarizing Client Side Asynchronous Invocations in WCF/WCF Silverlight" at http://www.codeproject.com/KB/silverlight/AsyncCallsWCFSilverlight.aspx.
See "Implement a Custom HTTP Handler" on MSDN at https://msdn.microsoft.com/en-us/library/ms228090.aspx
See "Creating an Asynchronous HTTP Handler" on MSDN at https://msdn.microsoft.com/en-us/library/ms227433.aspx.
Improve the performance of the data access layer by applying the following guidelines:
Change from Integrated Windows Authentication to SQL Server authentication. This allows you to use a simple user name and password that are stored in a trusted database. The performance overhead for Integrated Windows Authentication is high.
If the number of inbound and outbound messages is very large, you can implement paging in the WCF service layer, in both the client request and the WCF response. Paging is a technique that uses fewer messages. (Each message contains more data.) Paging reduces the number of round trips required between the client and the server. The following code demonstrates how to use paging.
Service-Consuming Client Side Paging
C# Code Version
public List<Item> GetItemsByTypeAndAccountNumber(int typeID, string strAccountNumber)
{
try
{
// Set the maximum pages possibly align with grid user interface
int iResultsPerPage = MaxPaging;
bool bCompleteFlag = true;
int iPageCounter = 1;
List<Item> tempList = new List<Item>();
if (typeID == 1)
// Get all records narrow down by account number
List<Item> retList = WCFServiceReference.GetAllRecords(accountNumber, iPageCounter, iResultsPerPage, out bCompleteFlag).ToList<Item>();
else
List<Item> retList = WCFServiceReference.GetAllRecords(iPageCounter, iResultsPerPage, out bCompleteFlag).ToList<Item>();
if (retList != null)
{
// We got results, but we need to check and see if there are more results
while (!bCompletFlag)
{
// try getting the next page
iPageCounter ++;
if (typeID == 1)
tempList = WCFServiceReference.GetAllRecords(accountNumber, iPageCounter, iResultsPerPage, out bCompleteFlag).ToList<Item>();
else
tempList = _ WCFServiceReference.GetAllRecords(iPageCounter, iResultsPerPage, out bCompleteFlag).ToList<Item>();
// add it to the main list
foreach (Item i in tempList)
{
retList.Add(i);
}
// clear the temp list
tempList.Clear();
}
}
return retList;
}
catch (Exception ex)
{
HandleException();
throw new Exception("Error getting records from the service layer: " + ex.Message, ex);
}
}
VB.NET Code Version
Friend Function GetItemsByTypeAndAccountNumber(typeID As Integer, _strAccountNumber As String) As List(Of Item)
Try
' We need to get all the results, one page at a time.
Dim iResultsPerPage As Integer = MaxPaging
Dim bCompleteFlag As Boolean = True
Dim iPageCounter As Integer = 1
Dim tempList As New List(Of Item)()
Dim retList As New List(Of Item)()
if (typeID == 1)
// Get all records narrow down by account number
retList = WCFServiceReference.GetAllRecords(accountNumber, iPageCounter, iResultsPerPage, out bCompleteFlag).ToList(Of Item)();
else
retList = WCFServiceReference.GetAllRecords(iPageCounter, iResultsPerPage, out bCompleteFlag).ToList(Of Item)();
If retList IsNot Nothing Then
' We got results, but we need to check and see if there are more results
While Not bCompleteFlag
' try getting the next page
iPageCounter += 1
if (typeID == 1)
// Get all records narrow down by account number
retList = WCFServiceReference.GetAllRecords(accountNumber, iPageCounter, iResultsPerPage, out bCompleteFlag).ToList(Of Item)();
else
retList = WCFServiceReference.GetAllRecords(iPageCounter, iResultsPerPage, out bCompleteFlag).ToList(Of Item)();
' add it to the main list
For Each i As Item In tempList
retList.Add(i)
Next
' clear the temp list
tempList.Clear()
End While
End If
Return retList
Catch ex As Exception
Throw New Exception("Error getting records from the service layer: " + ex.Message, ex)
End Try
End Function
Service Producing WCF Layer Paging
C# Code Version
public List<Item> GetAllRecords(string accountNumber, int iPageNumber, int iResultsPerPage, out bool bCompleteFlag)
{
int iTotalResults = 0;
int iTotalPages = 0;
bCompleteFlag = true;
int iStartIndex = 0;
List<Item> returnList = new List<Item>();
List<Item> recordList = new List<Item>();
recordList = WCFServiceReference.ERPInterfaceGetTransactions(accountNumber).ToList<Item>();
iTotalResults = recordList.Count();
iTotalPages = (int)System.Math.Ceiling((decimal)(iTotalResults / iResultsPerPage));
// check the bounds on the requested page number
if (iPageNumber > iTotalPages)
{
iPageNumber = iTotalPages;
}
else if (iPageNumber < 1)
{
iPageNumber = 1;
}
iStartIndex = (iPageNumber - 1) * iResultsPerPage;
var i = recordList.Skip(iStartIndex).Take(iResultsPerPage);
iTotalResults = recordList.Count;
if (iPageNumber > 0) // If it's <= 0, we'll just give all the results
{
iPageNumber -= 1; // Start by adjusting the page index for zero-based indices
iStartIndex = iPageNumber * iResultsPerPage; // For example, page num = 2, results/page = 10,
int iEndIndex = iStartIndex + iResultsPerPage; // We need to stop at the right place
if (iEndIndex >= recordList.Count)
{
bCompleteFlag = true;
iEndIndex = recordList.Count;
}
else
{
bCompleteFlag = false;
}
for (int i = iStartIndex; i < iEndIndex; i++)
{
returnList.Add(recordList[i]);
}
// Return a small subset
recordList = returnList;
}
return recordList;
}
VB.NET Code Version
Public Function GetAllRecords(accountNumber As String, iPageNumber As Integer, iResultsPerPage As Integer, ByRef bCompleteFlag As Boolean) As List(Of Item)
Dim iTotalResults As Integer = 0
Dim iTotalPages As Integer = 0
bCompleteFlag = True
Dim iStartIndex As Integer = 0
Dim returnList As New List(Of Item)()
Dim recordList As New List(Of Item)()
recordList = WCFServiceReference.ERPInterfaceGetTransactions(accountNumber).ToList(Of Item)()
iTotalResults = recordList.Count()
iTotalPages = CInt(Math.Truncate(System.Math.Ceiling(CDec(iTotalResults \ iResultsPerPage))))
' check the bounds on the requested page number
If iPageNumber > iTotalPages Then
iPageNumber = iTotalPages
ElseIf iPageNumber < 1 Then
iPageNumber = 1
End If
iStartIndex = (iPageNumber - 1) * iResultsPerPage
Dim i = recordList.Skip(iStartIndex).Take(iResultsPerPage)
iTotalResults = recordList.Count
If iPageNumber > 0 Then
' If it's <= 0, we'll just give all the results
iPageNumber -= 1
' Start by adjusting the page index for zero-based indices
iStartIndex = iPageNumber * iResultsPerPage
' For example, page num = 2, results/page = 10,
Dim iEndIndex As Integer = iStartIndex + iResultsPerPage
' We need to stop at the right place
If iEndIndex >= recordList.Count Then
bCompleteFlag = True
iEndIndex = recordList.Count
Else
bCompleteFlag = False
End If
For i As Integer = iStartIndex To iEndIndex - 1
returnList.Add(recordList(i))
Next
' Return a small subset
recordList = returnList
End If
Return recordList
From hop 4 (Node 5) – ERP with Application Servers Configuration Optimization:
This section lists web sites that explain how to optimize the front-end application servers of back-end ERP systems, such as SAP, Oracle ERP, or Lawson ERP. As back-end ERP systems were adapted to operate on the Internet, application servers became a viable solution for hosting legacy applications, and exposing ERP modules.
For additional information on Apache Server performance tuning, see http://httpd.apache.org/docs/2.0/misc/perf-tuning.html.
For additional information on WebLogic Server performance tuning, see http://download.oracle.com/docs/cd/E13222_01/wls/docs100/perform/WLSTuning.html#wp1152088.
For additional information on IBM WebSphere performance tuning, see http://www-01.ibm.com/software/webservers/appserv/was/performance.html.
The majority of application servers use Java. For more information on how to fine tune Java, go to http://java.sun.com/performance/reference/whitepapers/tuning.html.
Conclusion
SOA, or enterprise integration, integrates standard and non-standard technologies in an end-to-end solution that addresses a variety of business objectives. Implementing such a complex architecture requires detailed analysis, and highly disciplined design, development, and deployment initiatives. This article discussed the many tools that are available from Microsoft for configuring, fine-tuning, troubleshooting, and monitoring the performance of WCF services. There are also guidelines on how to design your solutions for performance and scalability. Finally, it included a broad range of configuration options for the end-to-end solution, from the client to the back-end ERP. It is recommended that you read the other articles that were mentioned here to get a better understanding of how to configure and troubleshoot your integration scenarios.
Additional Resources
https://support.microsoft.com/kb/821268.
For additional information about optimizing IIS 6.0, see "Optimizing IIS 6.0 Performance" on TechNet at https://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/e621190d-1015-40c2-a5ec-0dcb32c98286.mspx?mfr=true.
For additional information about optimizing IIS 7.0, see "Optimizing IIS 7.0 Performance" on TechNet at https://technet.microsoft.com/en-us/library/cc770381(WS.10).aspx
"Configuring Windows Communication Foundation Applications" on MSDN at https://msdn.microsoft.com/en-us/library/ms730120.aspx
"Windows Communication Foundation Configuration Schema" on MSDN at https://msdn.microsoft.com/en-us/library/ms731734.aspx
There is a useful discussion with procedures on optimizing the data access layer at this link: http://www.linkedin.com/answers/technology/software-development/TCH_SFT/416855-13606449
For additional information on Apache Server performance tuning, see http://httpd.apache.org/docs/2.0/misc/perf-tuning.html.
For additional information on WebLogic Server performance tuning, see http://download.oracle.com/docs/cd/E13222_01/wls/docs100/perform/WLSTuning.html#wp1152088.
For additional information on IBM WebSphere performance tuning, see http://www-01.ibm.com/software/webservers/appserv/was/performance.html.
The majority of application servers use Java. For more information on how to fine tune Java, go to http://java.sun.com/performance/reference/whitepapers/tuning.html.
Previous article: Performance and Scalability
Continue on to the next article: Dependency Injection in Windows Communication Foundation