Service throttling is one of the very useful features in WCF. You can simply configure your service with a custom service behavior to limit the number of service call, session and instance by using the following configuration:
However, the WCF service throttling is affecting service level only. What if you have a requirement that your service should be limited to accept only 3 requests per second? You cannot precisely do the restriction and controlling with service throttling. Therefore, we have to control the transaction limit at the code level instead, the idea comes from Serena Yeoh.
First, we have to create a WCF service. My service setup is as follow:
The GetData is one very simple and dumb operation. It just accept whatever string value and then return the same value back to client.
Next, your service has to be singleton. Why? Because I can only control the limit with 1 instance only.
The following is the method I used to control the transaction limit:
In order to test my service, I have created a console program to call my WCF service.
This is the result that I got, notice that there are only 3 transaction per second only even though I used parallel for loop to call my WCF service.
If you are interested with my source code, feel to download it from HERE.
<serviceBehaviors> <behavior name="MyBehavior"> <serviceThrottling maxConcurrentCalls="1" maxConcurrentSessions="1" maxConcurrentInstances="1" /> </behavior> </serviceBehaviors>
However, the WCF service throttling is affecting service level only. What if you have a requirement that your service should be limited to accept only 3 requests per second? You cannot precisely do the restriction and controlling with service throttling. Therefore, we have to control the transaction limit at the code level instead, the idea comes from Serena Yeoh.
First, we have to create a WCF service. My service setup is as follow:
[ServiceContract]
public interface ISampleService
{
[OperationContract]
string GetData(string value);
}
The GetData is one very simple and dumb operation. It just accept whatever string value and then return the same value back to client.
Next, your service has to be singleton. Why? Because I can only control the limit with 1 instance only.
[ServiceBehavior(InstanceContextMode
= InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
public class SampleService : ISampleService
The following is the method I used to control the transaction limit:
//Lock
an object to prevent multiple instance access / execute the following code at
the same time
lock (countLock)
{
//StopWatch timer started in constructor
//Check if the timer elapsed time is less than 1 second
//Check if the timer elapsed time is less than 1 second
if (watch.ElapsedMilliseconds <= 1000)
{
//If
there are 3 hits in less than 1 second
if (counter >= 3)
{
//Prepare to sleep
or wait until the next second time up
//Calculate the sleep time by using 1 second time minus the elapsed time
//Calculate the sleep time by using 1 second time minus the elapsed time
int sleepTime = (int)(1000 - watch.ElapsedMilliseconds);
counter = 1; //reset back the hit counter
Debug.WriteLine("Sleep :
" + sleepTime + " ms");
if (sleepTime >= 0)
Thread.Sleep(sleepTime);
watch.Restart();
}
else
{
//The
hit is still within the limit, let it pass
counter++;
}
}
else
{
//The
elapsed time has exceed 1 seconds
//Reset
the counter and timer
//Proceed
to process
counter = 1;
watch.Restart();
}
}
In order to test my service, I have created a console program to call my WCF service.
class Program
{
static void Main(string[] args)
{
//Parallelly
or concurrently hitting my service
//to
test whether the service process more than 3 transactions per second
Parallel.For(0, 100, i =>
{
SampleServiceClient proxy = new SampleServiceClient();
Console.WriteLine(string.Format(
"{0}
Service call {1} : {2}",
DateTime.Now.ToString("yyyy-MM-dd
hh:mm:ss.fff"),
i,
proxy.GetData("Test")));
});
Console.WriteLine("Press any
key to continue...");
Console.ReadKey();
}
}
This is the result that I got, notice that there are only 3 transaction per second only even though I used parallel for loop to call my WCF service.
If you are interested with my source code, feel to download it from HERE.
No comments:
Post a Comment