Every .NET developer must have written/used WCF services many times in different projects. But as long as the usage of the service are limited, it works smoothly. But as the number of requests increases rapidly, things starts become ugly. If the number of requests goes beyond a limit at certain time interval, you may start seeing critical issues like service may stop taking new request. As you will read this post, you will come to know the huge potential of your services and unseen ceiling applied by default configuration
In this post, I will be discussing two major items that can tremendously boost the performance of your services
1- WCF throttling
2- System.NET changes
Before moving ahead, the basic question arises that What is throttling?
In simple words, Throttling is a way to control or limit the number input(request) in a certain interval so that the resources at server stay at healthy state.
WCF throttling by default provides some throttling values set and allows us to configure that.
There are three main properties properties provided by default WCF throttling.
1- maxConcurrentCalls – How many number of request can be accepted by a service in a second.
2- maxConcurrentSessions – How many number of request can be processed by a service in a second.
3- maxConcurrentInstances – How many number of instances of service can be created by a service in a second.
Now let’s discuss one by one.
maxConcurrentCalls – denotes number of request can be accepted by service in a second. If the number of requests exceeds the set value, the request starting queuing up and if this goes on, the queue gets full and then further request start getting denied.
maxConcurrentSession – denotes the number of concurrent sessions in a second of a ServiceHost. If I elaborate it a bit, then in a sec, this number of requests can be in processing state.
maxConcurrentInstances – In a normal scenario (default case where we did not use any instance management) this number of instances can be created in a sec. So when a request comes to the service, a new instance is created to serve that request. Again if the number of instance throttle reached, no more instances would be created.
So before discussing further, can you think of any formula in these three?
So before wasting anymore time, let me reveal that.It means, say if we allow maxConcurrentcalls as X it means X instances would be made to handle at a specific point and maxConcurrentSessions as Y number of request that is getting processed which Y number of service instances. So maxConcurrentInstances should be set as X+Y..
I hope you all got the ideas about these settings. Now You will be amazed to see the default value of these setting. These are
maxConcurrentCalls – 16
maxConcurrentInstances – 26
So it means your service can take at max 16 calls and can have max 10 concurrent instances per sec. Don’t you thinnk that it is very less. In normal scenario if the service is consumed by a single client and number of calls per second is not much then you may not realize it.But if your service is consumed by 10 to 100s or more clients then some of the client start getting timeout or no response error from service.
Even I was working on a application which has WCF service, and it was getting more that 100 calls in a sec and WCF was silently started denying the request. After a lot of investigation I reached to the actual cause.
So now the bigger question – What should be the optimum value?
Now before moving further, the above values are default values if one is using .NET 4.0 or less. But if you are using the .NET 4.5, Microsoft made it dynamic and changed it significantly and as
maxConcurrentCalls – 16 times of number of processors
maxConcurrentSessions – 100 times of number of processors
maxConcurrentInstances – Sum of maxConcurrentCalls and maxConcurrentSession.
Normally at our production servers, we used 8 or 16 or more processors. Correct. let’s see the value in case of 8 cores
maxConcurrentCalls – 144
maxConcurrentSessions – 800
maxConcurrentInstances – 944
Earlier which was used to in 10s per sec, which is now in 100s. Awesome!!
So if we are using the default values then we are just victim of a default ceiling and can set it in config file as
<serviceBehaviors> ... <behavior name="myServiceBehavior"> <serviceThrottling maxConcurrentCalls="144" maxConcurrentInstances="944" maxConcurrentSessions="800" /> .. </serviceBehaviors>
if using earlier version of .NET framework 4.5 so we should modify it accordingly. If you are using .NET 4.5+ then you are lucky and can safely ignore it.
If your application server and WCF service is hosted on different servers then it may be again major bottleneck. This contains the settings that says how many outbound request can be made at a time to another server. And the default value is 2 per IP. It can be pictorially shown as
So what should be the optimum value. We can put it as per requirement say 100. But we should not put it to too high because if accidentally it started making calls to the service then it may be disastrous for our service. So make it reasonable and based on the requirement. It can be set as
<configuration> ... <system.net> <connectionManagement> <add address="*" maxconnection="100" /> </connectionManagement> </system.net> </configuration>
So I hope you enjoyed this post. Please feel free to share you precious comments.