binary dreams

a world of 1s and 0s

How to configure your unsecured WCF or ASMX service for round-robin load balancing

I was asked to investigate how to get our load balancing working with our services stack. Our services stack is used by many clients, a bespoke legacy Delphi EPOS application and various internal websites.

This blog post details how to load balance using an unsecured endpoint only. To use a secured endpoint needs further investigation. In our case an unsecured endpoint was acceptable because we are not communicating outside our company network.

The load balancer

We have a Netscaler hardware load balancer configured as Round-Robin with Persistence set to None. This means each call will go to the next server and the connection to a server will not be persisted. 

Our network guy configured the load balancer to call a url every 5 minutes - in this case a service. Once called it will return the service page and it will check for specific text and as long as that happens then its successful. Doing this gives us an early warning system if a service or IIS is down and adds to the practice of zero-downtime deployments. 

Enable your WCF Service to be load balanced

Add this binding to your web.config:

<bindings>
<customBinding>
<binding name="httpBinding">
<httpTransport keepAliveEnabled="false" />
</binding>
</customBinding>
</bindings>

 If you have existing applications that use an existing endpoint, do not replace it but add the following endpoint to your web.config. 

<services>
<service>
<endpoint address="http://fakehost/fakewebsite/FakeService.svc/custom" 
contract="FakeContract.IFakeContract" binding="customBinding" 
bindingConfiguration="httpBinding" name="custom" />
</service>
</services>

How to enable your client to call a load balanced application

Add this binding to your client app.config: 

<bindings>
<customBinding>
<binding name="httpBinding">
<httpTransport keepAliveEnabled="false" />
</binding>
</customBinding>
</bindings>
Add this endpoint to your client app.config:
<client>
<endpoint address="http://fakehost/fakewebsite/FakeService.svc/FakeService/basic" 
contract="FakeContract.IFakeContract" binding="customBinding" 
bindingConfiguration="httpBinding" name="basic" />
</client>
 
Your local network admin might advise that you need to add this <bypasslist> element to a <defaultProxy>: 
<system.net>
<defaultProxy enabled="true" useDefaultCredentials="true">
<bypasslist>
<add address="10.*"/>
</bypasslist>
<proxy autoDetect="False" proxyaddress="http://fakeproxy" bypassonlocal="True" />
</defaultProxy>
</system.net>

You don't want to go via your network proxy if you don't need to. It's inefficient.

How to call a load balanced ASMX service

To call an ASMX service that is load balanced you must add the following custom binding and a similar endpoint.

<system.serviceModel>
<bindings>
<customBinding>
<binding name="HttpBinding">
<textMessageEncoding messageVersion="Soap11" />
<httpTransport keepAliveEnabled="false" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://fakeserver/FakeService/Fake.asmx" 
binding="customBinding" bindingConfiguration="HttpBinding" 
contract="FakeProxyServiceReference.FakeSoap" name="CustomBinding_HttpBinding" />
</client>
</system.serviceModel>