One way to increase the capacity of Windows Communication Foundation (WCF) applications is to scale them out by deploying them into a load-balanced server farm. WCF applications can be load balanced using standard load balancing techniques, including software load balancers such as Windows Network Load Balancing as well as hardware-based load balancing appliances.
The following sections discuss considerations for load balancing WCF applications built using various system-provided bindings.
From the perspective of load balancing, WCF applications that communicate using the BasicHttpBinding are no different than other common types of HTTP network traffic (static HTML content, ASP.NET pages, or ASMX Web Services). WCF channels that use this binding are inherently stateless, and terminate their connections when the channel closes. As such, the BasicHttpBinding works well with existing HTTP load balancing techniques.
By default, the BasicHttpBinding sends a connection HTTP header in messages with a Keep-Alive value, which enables clients to establish persistent connections to the services that support them. This configuration offers enhanced throughput because previously established connections can be reused to send subsequent messages to the same server. However, connection reuse may cause clients to become strongly associated to a specific server within the load-balanced farm, which reduces the effectiveness of round-robin load balancing. If this behavior is undesirable, HTTP Keep-Alive can be disabled on the server using the KeepAliveEnabled property with a CustomBinding or user-defined Binding. The following example shows how to do this using configuration.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="Microsoft.ServiceModel.Samples.CalculatorService" behaviorConfiguration="CalculatorServiceBehavior"> <host> <baseAddresses> <add baseAddress="http://localhost:8000/servicemodelsamples/service"/> </baseAddresses> </host> <!-- configure http endpoint, use base address provided by host And the customBinding --> <endpoint address="" binding="customBinding" bindingConfiguration="HttpBinding" contract="Microsoft.ServiceModel.Samples.ICalculator" /> </service> </services> <bindings> <customBinding> <!-- Configure a CustomBinding that disables keepAliveEnabled--> <binding name="HttpBinding" keepAliveEnabled="False"/> </customBinding> </bindings> </system.serviceModel> </configuration>
Using the simplified configuration introduced in .NET Framework 4, the same behavior can be accomplished using the following simplified configuration.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <protocolMapping> <add scheme=”http” binding=”customBinding” /> </protocolMapping> <bindings> <customBinding> <!-- Configure a CustomBinding that disables keepAliveEnabled--> <binding keepAliveEnabled="False"/> </customBinding> </bindings> </system.serviceModel> </configuration>
Turn off Security Context Establishment: this can be accomplished by the setting the EstablishSecurityContext property on the WSHttpBinding to false. Alternatively, if security sessions are required, it is possible to use stateful security sessions as described in the Secure Sessions topic. Stateful security sessions enable the service to remain stateless as all of the state for the security session is transmitted with each request as a part of the protection security token. Note that to enable a stateful security session, it is necessary to use a CustomBinding or user-defined Binding as the necessary configuration settings are not exposed on WSHttpBinding and WSDualHttpBinding that are provided by the system.
Do not use reliable sessions. This feature is off by default.
The NetTcpBinding can be load balanced using IP-layer load balancing techniques. However, the NetTcpBinding pools TCP connections by default to reduce connection latency. This is an optimization that interferes with the basic mechanism of load balancing. The primary configuration value for optimizing the NetTcpBinding is the lease timeout, which is part of the Connection Pool Settings. Connection pooling causes client connections to become associated to specific servers within the farm. As the lifetime of those connections increase (a factor controlled by the lease timeout setting), the load distribution across various servers in the farm becomes unbalanced. As a result the average call time increases. So when using the NetTcpBinding in load-balanced scenarios, consider reducing the default lease timeout used by the binding. A 30-second lease timeout is a reasonable starting point for load-balanced scenarios, although the optimal value is application-dependent. For more information about the channel lease timeout and other transport quotas, see Transport Quotas.