尝试并行运行多个HTTP请求,但被Windows(registry)限制
我正在开发一个应用程序(winforms C#.NET 4.0),我通过一个简单的HTTP请求从第三方访问查找function。 我用一个参数调用一个url,并返回一个小string,查找的结果。 很简单。
然而挑战是我必须做很多这样的查找(几万),而且我想限制所需的时间。 所以我想平行运行请求(比如10-20)。 我使用一个ThreadPool来做到这一点,我的代码的短版本看起来像这样:
public void startAsyncLookup(Action<LookupResult> returnLookupResult) { this.returnLookupResult = returnLookupResult; foreach (string number in numbersToLookup) { ThreadPool.QueueUserWorkItem(lookupNumber, number); } } public void lookupNumber(Object threadContext) { string numberToLookup = (string)threadContext; string url = @"http://some.url.com/?number=" + numberToLookup; WebClient webClient = new WebClient(); Stream responseData = webClient.OpenRead(url); LookupResult lookupResult = parseLookupResult(responseData); returnLookupResult(lookupResult); }
我从另一个地方填充numbersToLookup
(一个List<String>
),调用startAsyncLookup
并提供一个callback函数returnLookupResult
来返回每个结果。 这工作,但我发现我没有得到我想要的吞吐量。
起初,我认为这可能是第三方在他们的最后一个穷人的系统,但我排除了这一点,试图从两个不同的机器同时运行相同的代码。 两个人都独自一人,所以我可以排除一个。
一个同事然后告诉我,这可能是在Windows中的限制。 我GOOGLE了一下,发现其中包括其他人这篇文章说,默认情况下,Windows限制同一个Web服务器的请求数为4对于HTTP 1.0和2对于HTTP 1.1(对于HTTP 1.1这实际上是根据规范RFC2068))。
上面提到的同一个post也提供了一个增加这些限制的方法。 通过将两个registry值添加到[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings]
(MaxConnectionsPerServer和MaxConnectionsPer1_0Server),我可以自己控制这个。
所以,我试了这个(坐到20),重新启动我的电脑,并试图再次运行我的程序。 可悲的是,似乎没有任何帮助。 在运行批处理查找时,我还一直关注资源监视器( 请参阅屏幕快照 ),并且我注意到我的应用程序(标题为黑屏的应用程序)仍然只使用两个TCP连接。
所以,问题是,为什么这不工作? 是我链接到使用错误的registry值? 这可能无法在Windows中“破解”(我在Windows 7上)吗?
任何想法将不胜感激:)
而且万一有人想知道,我也尝试了ThreadPool上MaxThreads的不同设置(从10到100),这似乎没有影响我的吞吐量,所以问题也不应该存在。
这是ServicePoint的问题 。 它为HTTP连接提供连接pipe理。 ServicePoint对象允许的默认最大并发连接数是2.所以,如果你需要增加它,你可以使用ServicePointManager.DefaultConnectionLimit属性。 只需检查MSDN中的链接,您可以看到一个示例。 并设置你需要的值。
为了更快的参考某人。 要增加每个主机的连接限制,您可以在开始进行HTTP请求之前,在Main()或任何时候执行此操作。
System.Net.ServicePointManager.DefaultConnectionLimit = 1000; //or some other number > 4
从你的主要方法中解雇这个方法。 Icognito用户是正确的,只允许2个线程同时播放。
private static void openServicePoint() { ServicePointManager.UseNagleAlgorithm = true; ServicePointManager.Expect100Continue = true; ServicePointManager.CheckCertificateRevocationList = true; ServicePointManager.DefaultConnectionLimit = 10000; Uri MS = new Uri("http://My awesome web site"); ServicePoint servicePoint = ServicePointManager.FindServicePoint(MS); }
对于Internet Explorer 8:运行registry编辑器并导航到以下registry项HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Internet Explorer \ MAIN \ FeatureControl \ FEATURE_MAXCONNECTION SPERSERVER
和
HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Internet Explorer \ MAIN \ FeatureControl \ FEATURE_MAXCONNECTION SPER1_0SERVER
如果缺lessFEATURE_MAXCONNECTIONSPERSERVER和FEATURE_MAXCONNECTIONSPER1_0SERVER,则创build它们。 现在为两个子键(上面列出)创build名为iexplore.exe的DWORD值,并将它们的值设置为10或任何所需的数字。