This is not a new topic in the world of traditional web service usage. But I was still asked by people who use WCF. So I think it would be valuable to post a blog entry here. One of our customers asked me the following question:
“We are using WCF in our application on Windows 2008 Server. We found the web role instance only have two concurrent threads to handle the incoming requests no matter how many requests we throw into it. We tried 50, 100, 200 clients sending requests to the WCF service at the same time. But web role only have two threads to handle it. We used the following settings in the web.config to set up the number of threads for WCF. But it seems not work. Why is that?”
<serviceThrottling maxConcurrentCalls="32" maxConcurrentInstances="100" maxConcurrentSessions="20"/>
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.
There is no other place that has a throttling of “2” on the server side. If you really want to know how many outstanding requests are processed by WCF, you can enable WCF performance counters and check “Calls Outstanding”. It will tell you that information.
Then the real problem should be on the load testing client. There is an apparent throttling on the client side that has default value 2: “maxconnection” from System.Net. This setting is according to RFC 2616, the RFC for Hypertext Transfer Protocol -- HTTP/1.1:
"Clients that use persistent connections SHOULD limit the number of simultaneous connections that they maintain to a given server. A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy. A proxy SHOULD use up to 2*N connections to another server or proxy, where N is the number of simultaneously active users. These guidelines are intended to improve HTTP response times and avoid congestion."
So for load testing purpose, you should increase this setting to an appropriate limit. You can find a lot of documents on how to set this setting. Let me simply re-iterate it here.
1) Using <connectionManagement> configuration
You can use the following configuration to tune this setting:
You can use address=”*” to set the same setting for all remote addresses.
2) Setting it from code with ServicePointManager.DefaultConnectionLimit
You can also set the setting from code before you call into any web service:
System.Net.ServicePointManager.DefaultConnectionLimit = 16;
After this, you would see your client application generate more concurrent requests to the server.