Thursday, February 10, 2011

WCF Performance Tuning(ZT)

 

From http://www.aspnet101.com/2010/08/wcf-performance-best-practices/

 

WCF was introduced to overcome the constraints of previous distributed technologies like ASP.NET Web Services, WSE, .NET Enterprise Services and .NET Remoting and to provide a performance boost in addition. For an introduction to WCF please read my first WCF article - WCF Tutorial .

Performance is a central goal for web or app site, expecially since Google now includes site responsiveness a factor in their ranking algorithm.  For ASP.NET optimization tips, please see  my article titled 50 Tips to Boost ASP.NET Performance.  In this article I will  discuss   WCF performance tuning techniques.

Use DataContractSerializer:

Serialization  is the process of converting an object instance into a portable and transferable format.   Xml Serialization  is popular for its interoperability and binary Serialization  is more useful for transferring objects between two .NET  applications.

System.Runtime.Serialization.DataContractSerializer is   designed for WCF but can also be used for general serialization. The DataContractSerializer has some benefits over XmlSerializer:

  1. XmlSerializer can serialize only properties but DataContractSerializer can serialize fields in addition to  properties.
  2. XmlSerializer can serialize only public members but DataContractSerializer can serialize not only public members but also private and protected members.
  3. In performance terms,  DataContractSerializer is approximately 10% faster than XmlSerializer.

Select proper WCF binding:

System-provided WCF bindings are used to specify the transport protocols, encoding, and security details required for clients and services to communicate with each other. The below are the available  system-provided WCF bindings:

1.BasicHttpBinding:

A binding   suitable for communication with WS-Basic Profile conformant Web Services such as ASMX-based services. This binding uses HTTP as the transport and Text/XML for message encoding.

2. WSHttpBinding:

A secure and interoperable binding   suitable for non-duplex service contracts.

3. WSDualHttpBinding:

A secure and interoperable binding  suitable for duplex service contracts or communication through SOAP intermediaries.

4. WSFederationHttpBinding:

A secure and interoperable binding that supports the WS-Federation protocol, enabling organizations that are in a federation to efficiently authenticate and authorize users.

5. NetTcpBinding:

A secure and optimized binding suitable for cross-machine communication between WCF applications

6. NetNamedPipeBinding:

A  reliable, secure, optimized binding suitable for on-machine communication between WCF applications.

7. NetMsmqBinding:

A queued binding suitable for cross-machine communication between WCF applications.

8. NetPeerTcpBinding :

A binding which enables secure, multi-machine communication.

9. MsmqIntegrationBinding :

A binding that is suitable for cross-machine communication between a WCF application and existing MSMQ applications.

In this context Juval Lowry has presented a nice decision making diagram:

WCF Performance Tuning

It should be noted that WCF also allows us to define our own custom bindings.

Use Tracing:

Tracing can track all the events or specified events in a  program. By default it is off. For debugging purposes we have to make enable it explicitly either through code or using a config file setting which is preferable. If  debugging is not required we should disable tracing. For more details reader can read my article titled “Tracing in WCF”.

Close Proxy:

The proxy represents a service contract. It provides the same operations as service’s contract along with some additional methods for managing the proxy life cycle and the connection to the service. It is a recommended best practice to always close the proxy when the client is finished using it. When we close the proxy, the session with the service is terminated and the connection is closed as well and thus can serve to process new requests in better way.

It should be noted that calling a proxy in a using statement (see the below code snippet) is actually not the optimal  or safest method.

using (ServiceProxy proxyClient = new ServiceProxy())
{
proxyClient.SomeFunction();
}
The above code will be translated to something as follows:
ServiceProxy proxyClient = new ServiceProxy();
try
{
proxyClient.SomeFunction();
}
finally
{
if (proxyClient != null)
((IDisposable)proxyClient).Dispose();
}


The problem with this method is that proxyClient.Dispose() will throw an exception when the proxy is in a faulted state .So to close the proxy even under faulted state the below is the suggested approach:



ServiceProxy proxyClient = new ServiceProxy();
try
{
proxyClient.SomeFunction();
proxyClient.Close();
}
finally
{
if (proxyClient.State != System.ServiceModel.CommunicationState.Closed)
{
proxyClient.Abort();
}
}


Throttling:



Throttling is a way of mitigating potential DoS (denial of service) attacks. Using ServiceThrottlingBehavior we can set smooth loading and resource allocations on the server. In WCF, there are three service-level throttles that are controlled by ServiceThrottlingBehavior.



1. MaxConcurrentCalls: The maxConcurrentCalls attribute lets us specify the maximum number of simultaneous calls for a service. When the maximum number of simultaneous calls has been met and a new call is placed, the call is queued and will be processed when the number of simultaneous calls is below the specified maximum number. The default value is 16.



2. MaxconcurrentSessions: The maxconcurrentSessions attribute specifies the maximum     number of connections



to a single service. The channels below the specified limit will be active/open. It should be noted that this throttle is effectively disabled for non-sessionful channels (such as default BasicHttpBinding).The default value is 10.



3. MaxConcurrentInstance: The maxConcurrentInstance attribute specify the maximum number of simultaneous service instances. While receiving new instance request the maximum number has already been reached, the request is queued up and will be completed when the number of instances is below the specified maximum. The default value is total of the two attributes maxConcurrentSessions and maxConcurrentCalls.



From general feedback it is has been noted that the default settings for the above mentioned three attributes are very conservative and are insufficient in real production scenarios and thus developers need to increase those default settings.



Hence Microsoft has increased the default settings in WCF4.0 as follows:



1. MaxConcurrentSessions: default is 100 * ProcessorCount



2. MaxConcurrentCalls: default is 16 * ProcessorCount



3. MaxConcurrentInstances: default is the total of MaxConcurrentSessions and MaxConcurrentCalls



Now we have a new parameter which is the multiplier “ProcessorCount” for the settings. The main reason for this is that we do not need to change the settings in deployment from a low end system to a multiple processor based system. The value for MaxConcurrentSessions is also increased from 10 to 100.



Quotas:



There are three types of quotas in WCF transports:



1. Timeouts. Timeouts are used for the mitigation of DOS attacks which rely on tying up resources for an extended period of time.



2. Memory allocation limits: Memory allocation limits prevent a single connection from exhausting the system resources and denying service to other connections.



3. Collection size limits: Collection size limits restrict the consumption of resources which indirectly allocate memory or are in limited supply.



As per MSDN the transport quotas available for the standard WCF transports: HTTP(S), TCP/IP, and named pipes are



as follows:



image 


 xxx


Other quotas of the ReaderQuotas property that can be used to restrict message complexity to provide protection from denial of service (DOS) attacks, these are:




  1. MaxDepth: The maximum nested no depth per read. The default is 32.


  2. MaxStringContentLength: The maximum string length allowed by the reader.  The default is 8192.


  3. MaxArrayLength: The maximum allowed array length of data being received by WCF from a client. The default is 16384.


  4. MaxBytesPerRead: The maximum allowed bytes returned per read.  The default is 4096.


  5. MaxNameTableCharCount: The maximum characters in a table name. The default is 16384.



The maxConnections property setting of NetTcpBinding on the client indicates the maximum number of connections to be pooled/cached for subsequent reuse.  On the server, this setting is responsible for controlling the maximum number of connections.  The default is 10. This helps performance in cases where we are creating and disposing client channels.



maxItemsInObjectGraph: The maximum number of items which can be serialized or desterilized in an object is 65,536.But this can be increased to  Int32.MaxValue (2147483647) and can be configured through behaviors in configuration file as follows: Once this behavior is set, the WCF service and client can send and receive not only large



objects, but also highly complex ones. The  below is the sample configuration settings:



<behaviors>


<serviceBehaviors>


<behavior name="largeObjectGraph">


<dataContractSerializer maxItemsInObjectGraph=”100000″/>”


</behavior>


</serviceBehaviors>


<endpointBehaviors>


<behavior name=”largeObjectGraph”>


<dataContractSerializer maxItemsInObjectGraph=”100000″/>”


</behavior>


</endpointBehaviors>


</behaviors>



The value needs to be set in both the client and the server.



Reliable Session:



Reliable sessions provide low-latency (Latency is the time requires for the message to reach the destination from the source) reliable message transfers. When using a reliable session, we should set a reasonable value for InactivityTimeout which is added to the binding configuration to keep the connection alive. At the same time the ReceiveTimeout setting of the binding is also need to be set with a reasonable value. If either of these is triggered, then the connection is killed. The default for both of these timeouts is 10 minutes. Following is the sample configuration settings:



<reliableSession enabled="true" ordered="true" inactivityTimeout="00:10:00"/>


Ideal Hosting Environment:



It is best to use IIS or WAS for robust, highly scalable services and self-hosting is ideal for a Windows Service to have full control and light-weight hosting environment. For more details user can read Optimal Hosting Environment



Chunking Channel:



In case of large amounts of data chunking, channels is a very handy solution. For more user can visit the link:Chunking channel



Use Cache:



Use caching intensively (but wisely) to save unnecessary round trips specifically for static types of data.



Asynchronous WCF HTTP Module/Handler:



For optimal server scalability there is a new addition, namely asynchronous WCF HTTP Module/Handler for IIS7. For more details see: Asynchronous WCF HTTP Module/Handler



Conclusion:



So far we have seen a few best practices in our service based application using WCF. Last but not least, when getting timeout exceptions we should bump up the default conservative settings inthe  Bindings, Behaviors and Serializers but not blindly to int.MaxValue.



Unfortunately, there is no magic formula to use – it depends on the volume and structure of an application’s data .It is advisable to load data during testing and find out a reasonable setting trial and error.

0 Comments:

Post a Comment

<< Home