views:

84

answers:

2

I'm building a server application that needs to perform a lot of http requests to a couple other servers on an ongoing basis. Currently, I'm basically setting up about 30 threads and continuously running HttpWebRequests synchronously on each thread, achieving a throughput of about 30 requests per second.

I am indeed setting the ServicePoint ConnectionLimit in the app.config so that's not the limiting factor.

I need to scale this up drastically. At the very least I'll need some more CPU horse power, but I'm wondering if I would gain any advantages by using the async methods of the HttpWebRequest object (eg: .BeginGetResponse() ) as opposed to creating threads myself and using the synchronous methods (eg: .GetResponse() ) on these threads.

If I go with the async methods, I obviously have to significantly redesign my app, so I'm wondering if anyone might have some insight before I go and recode everything, in case I'm out to lunch.

Thanks!

A: 

Fastest result so far for me is using 75 threads running sync httpwebrequest. About 140 requests per second on a windows 2003 server, 4core 3ghz, 100mb connection.

Async Httprequest / winsock got stuck at about 30-50 req/sec. Did not test sync winsock but I guess it would give you about the same result as httpwebrequest.

Tests was against 1 200 000 blog feeds.

Been struggling with this the last month so it would be interesting to know if someone managed to squeeze more out of .net?

EDIT

New test: Got 350req/sec with the xfserver iocp component. Used a bunch of threads with one instance each before any greater result. The "client part" of the lib had a couple of really annoying bugs that made implementation harder then the "server part". Not what you're asking for and not recommended but some kind of step.

Next: Former winsock test did not use the 3.5 SocketAsyncEventArgs, that will be next.

ANSWER

The answer to your question, no it will not be worth the effort. The async HttpWebRequest methods offloads main thread while keeping download in background, it does not improve the number/scalability of requests. (at least not in 3.5, might be different in 4.0?)

However, what might be worth looking at is building your own wrapper around async sockets/SocketAsyncEventArgs where iocp works and perhaps implement a begin/end pattern similar to HttpWebRequest (for easiest possible implementation in current code). The improvement is really enormous.

Simon Karlsson
I was under the impression that Async HttpWebRequests should be using IO Completion ports which I thought was different than the default ThreadPool...I'm a bit confused now as I would have expected that to be way faster than synchronous webreqeusts on a bunch of threads...
Redth
Yes it should, but so far I've yet to seen any working client example that gets above 50 simultaneous request. In my case I parse the first bytes to check that it actually is a xml feed, I guess that any parsing/result still would be done on a pooled worker thread. I might be wrong but my guess is that .net async requests is mainly aiming for background downloads without blocking ui thread in gui applications - not to run as many simultaneous request as possible.
Simon Karlsson
+1  A: 

If you are on Windows NT, then System.Net.Sockets.Socket class always uses IO Completion ports for async operations. And HTTPWebRequest in async mode uses async sockets, and hence will be using IOCP.

Without doing detailed benchmarking, it is difficult to say if our bottleneck is inside HttpWebRequest, or up the stack, in your application, or on the remote side, in the server. But offhand, for sure, asyncc will give you better performance, because it will end up using IOCP under the covers. And reimplementing the app for async is not that difficult.

So, I would suggest that you first change your app architecture to async. Then see how much max throughput you are getting. Then you can start benchmarking and finding out where the bottleneck is, and removing that.

feroze