I'm attempting to load test a WCF service with (IIS6/Server2003/BasicHttpBinding). The service is throttled as follows:
<serviceThrottling maxConcurrentCalls="100" maxConcurrentSessions="100" maxConcurrentInstances="100"/>
To assess the number of calls on the server I'm using the ServiceModelService 3.0.0.0 performance counters. If I throttle the maxConcurrentCalls down to 20, 15, 10 or anything lower the Instances performance counter show that WCF is respecting the throttling. However, if I change maxConcurrentCalls to 30 I'm never able to get Instances to go above 24. Additionally, Calls Outstanding never goes above 24. What else could be limiting WCF?
See Why Only Two Concurrent Requests for WCF Load Testing?
When I looked at this question, my
first response is that: the client did
not really send enough requests to the
server. Why is that? Here are the
reasons:
1) If you use the synchronous WCF
HttpModule/HttpHandler (installed by
default), you would get the maximal
number of concurrent requests (held by
that number of ASP.NET worker threads)
as 12 * [Number of CPU for the
Server].
2) WCF throttling is
specified above.
Related
I currently have a WCF service which uses BasicHTTP binding, and is wrapped with a secure router/firewall (PFSense).
I have heard that there is a faster binding than BasicHTTP binding, but I do now know what it is.
Does anyone know?
Update: ok, two great answers for intranet/localhost. Thank you!
What about for internet deployed apps? Is there a faster internet centric solution?
If your solution is deployed to an intranet, you can use NetTcpBinding.
http://msdn.microsoft.com/en-us/library/system.servicemodel.nettcpbinding.aspx
While perhaps not authoratative, this post covers some benchmarking with these results, which are consistent with my answer and parapura's:
WSDualHttpBinding: Processed 1602 calls in 10 seconds
WSHttpBinding: Processed 2531 calls in 10 seconds
BasicHttpBinding: Processed 17913 calls in 10 seconds
NetTcpBinding: Processed 39957 calls in 10 seconds
NetNamedPipeBinding: Processed 48255 calls in 10 seconds
On the same machine you can use NetNamedPipeBinding for maximum performance.
Decision Points for Choosing a Transport
Throughput measures the amount of data that can be transmitted and processed in a specified period of time. Like latency, the chosen transport can affect the throughput for service operations. Maximizing throughput for a transport requires minimizing both the overhead of transmitting content as well as minimizing the time spent waiting for message exchanges to complete. Both the TCP and named pipe transports add little overhead to the message body and support a native duplex shape that reduces the wait for message replies.
I have got the following scneario:
Our .NET client calls our WCF service - which in turn calls an external third party service to retrieve some data. Once the data is retrieved, our WCF service sets some values and then returns the control back to the client. The process of calling the external service has to be synchronous.
My problem is that this all works in a low load environment but when load gets high then we start queueing multiple requests, the WCF service starts timing out. We have set the "sendTimeout" property for the binding to 5 seconds and it times out after that.
I've tried replacing the external service with a mocked out local version and that handles the load OK but on the same hand the call to external service on it own is very quick - around 0.5 second. I can only presume that the timeouts are happening because too many requests were queued and WCF service couldn't respond within those allocated 5 seconds.
I have tried the following:
Set the values of maxConcurrentCalls, maxConcurrentSessions & maxConcurrentInstances to very high numbers
Set the value of system.net - connectionManagement - maxconnection to a very high number
Does any one have any ideas about what we can do in this scneario?
does your cpu peak during these high load times ? if not then you might be running out of threads. Make your wcf service that receives the original call asynchronous, and then call the external service asynchronously.
you will have to use asnyc pattern throughout your call chain to make sure nothing is blocking the thread.
http://msdn.microsoft.com/en-us/library/ms731177.aspx
I'm using perfmon to examine my service behaviour. What I do is I launch 6 instances of client application on separate machines and send requests to server in 120 threads (20threads per client application).
I have examined counters and maximum number of instances (I use PerSession model and set number of instances to 100) is 12, what I consider strange as my response times from service revolve around 120 seconds... I thought that increasing number of instances will cause WCF to create more instances, and as a result response times would be quicker.
Any idea why WCF doesn't create even more instances of service?
Thanks Pawel
WCF services are throttled by default - it's a service behavior, which you can tweak easily.
See the MSDN docs on ServiceThrottling.
Here are the defaults:
<serviceThrottling
maxConcurrentCalls="16"
maxConcurrentInstances="Int.MaxValue"
maxConcurrentSessions="10" />
With these settings, you can easily control how many sessions or concurrent calls can be handled, and you can make sure your server isn't overwhelmed by (fraudulent) requests and brought to its knees.
Ufff, last attempt to understand that silly WCF.
What I did now is:
create client that starts 20 threads, every thread sends requests to service in a loop. Performance counter on server claims that only 2 instances of service object are created all the time. Average request time is about 40seconds (I start measuring before proxy call and finish after call returns).
modify that client to start 5 threads and launch 4 instances of that client (to simulate 20 threads behaviour from previous example). Performance monitor shows that 8 instances of service object are created all the time. Average request time is 20seconds.
Could somebody tell me what is going on? I thought that there is a problem with server that it doesn't want to handle more requests at concurently, but apparently it is client that causes a stir and don't want to send more requests concurently... Maybe there is some kind of configuration option that limits client from sending more then two requests at one time... (buffer,throttling etc...)
Channel factory is created in every thread.
You might want to refer to this article and make adjustment to your WCF configuration (specifically maxConnections) to get the number of connections you want.
Consider using something like http://www.codeplex.com/WCFLoadTest to hit the service.
Also, perfmon will only get you so far. If you want to debug WCF service you should look at the SvcTraceViewer and SvcConfigEditor in the Windows SDK.
On your service binding what have you set the maxconnections to? Calls to connect will block once the limit is reached.
Default is 10 I think.
http://msdn.microsoft.com/en-us/library/ms731379.aspx
I have to create a WCF service that will accept thousands of requests every 5 minutes, which each request passing a small (1-5KB) text file.
The service will pass the file contents to another assembly, which will process the lines and insert some records into the database. Nothing too heavy on this side.
I need help on the following aspects:
Which WCF configuration should I use that will give me the best performance? The calls to the service will come from the internet not an internal LAN.
The service will accept requests every 5 minutes, which means I have only 5 minutes to process all the requests before the next cycle. Is MSMQ the best solution here?
Any examples online I can read?
For best performance, I'll assume you're talking about less latency. You should pick a TCP transport, like net.tcp. This document can help you to decide Choosing a Transport
About that MSMQ part: you'll receive a lot request and just start processing them after 5 minutes? If yes, your choice is correct: MSMQ will keep that request queue and you can work on them asynchronously.
Use NetTCPbinding
Optimizing WCF Web Service Performance
Creating high performance WCF services
I have a WCF net.tcp service hosted with the builtin ServiceHost, and when doing some stress tests I get a strange behavior. The first time i send a bunch of requests, 5 to 10 requests are answered quickly, and the rest are returning at about 2 second intervals. The second time i send the requests, 10 - 20 are returned quickly, and rest with 2 sencond intervals.
The above repeats until I can get over 100 requests returned quickly, but if I wait a minute or so the memory usage of the service goes down and the requests go back to 5-10 returning quick.
The service I am testing has a small delay, so that I can get many open connections at the same time, if this delay is removed the requests return so quickly that i have perhaps 2-5 connections open at the same time. This delay is to simulate DB connections and other outgoing stuff.
From the behavior it looks like the ServiceHost is allocating something, threads, class instances, but I can not figure out what it is.
I could have a timer in the client that calls the service to keep it working, but that seems like a bad solution.
If I have a high sustained load to the service it will crunch all requests quickly, but if I have a period of low activity and then a surge of connections comes in the service will be slow.
I guess my question is WHAT is it the get allocated during high load of the WCF service, and HOW can I configure the service to preallocate more of the things that get allocated.
EDIT:
I did some more testing, and looking at the taskmgr for the process I can see that when the servicehost is 'resting' there are 10 threads open, but when I start sending requests, the threadcount goes up. As long as the threadcount is high the servicehost can process incoming requests quickly, but if I pause sending the requests, the open threadcount decreases, and subsequent requests starts taking longer time to process.
Now, how can I tell the servicehost to keep a bunch of threads open? Or more than the 10-12 that it keeps by default?
Well, after lots of googling, it seems that the problem is the threadpool. The CLR threadpool allocates a few threads, and when they are used, it throttles the creation of new threads, and after a time it also deallocates unused threads.
There is some confusion about a bug that meant that the ThreadPool did not honor the SetMinThreads call.
http://www.michaelckennedy.net/blog/PermaLink,guid,708ee9c0-a1fd-46e5-8fa0-b1894ad6ce0f.aspx
I am not sure if this bug is solved, or what, because when I modify the ThreadPool settings, the problem persists.
The thing that determines how may request are handled simultaneous is the ServiceThrottlingBehavior. There are a number of different threasholds that will limit the amount of request being processed. This also depends on the binding your are using, for example wsHttpBinding defaults to sessions on while basicHttpBinding uses no sessions and the default session limit of 10 is no problem.
See http://msdn.microsoft.com/en-us/library/ms735114.aspx for more details.
The bug you referenced is fixed in .NET 3.5 SP1. That may have had something to do with the problem, I think it's more likely (much more likely) that throttling is your problem rather than thread as Maurice keyed into.
<system.serviceModel>
<service name="???" >
<endpoint ... />
</service>
</system.serviceModel>
What's the throttle limit for this "empty" config? 10 session, 16 concurrent calls! Beware.
Here's more on the threading:
http://www.michaelckennedy.net/blog/2008/08/20/ThreadPoolBugInNET20SP1IsFixed.aspx
This feels like a hack but it seems to solve your issue. The problem is that the threadpool will take time to start up a new thread, so what you really need is threads waiting on standby. Add a constructor to your service and set the minimum number of threads you would like.
public YourService()
{
int workerThreads;
int portThreads;
ThreadPool.GetMinThreads(out workerThreads, out portThreads);
ThreadPool.SetMinThreads(200, portThreads);
}