我们有一个应用程序(元搜索引擎),它必须经常为响应用户操作制作50到250个出站HTTP连接。
我们这样做的方法是创建一堆HttpWebRequests并使用Action.BeginInvoke异步运行它们。这显然使用ThreadPool来启动Web请求,这些请求在自己的线程上同步运行。请注意,它目前是这种方式,因为它最初是一个.NET 2.0应用程序,并且没有TPL可言。
使用ETW(我们的事件源结合.NET框架和内核)和NetMon是,虽然线程池可以在大约300ms内启动运行我们的代码的200个线程(因此,这里没有线程池耗尽问题),它占用了一个可变的时间,有时长达10-15秒,Windows内核可以使所有已排队的TCP连接。
这在NetMon中非常明显 - 你会看到大约60 - 100个TCP连接立即打开(SYN)(数量变化,但它永远不会超过120),然后其余部分在一段时间内涓涓细流。这就好像连接正在某个地方排队,但我不知道在哪里,我不知道如何调整它以便我们可以执行更多的并发传出连接。 Perfmon出站连接队列保持为0,但在Connections Established计数器中,您可以看到连接的初始峰值,然后随着其余的过滤逐渐增加。
我们所连接的端点的延迟似乎确实起到了作用,因为运行靠近它连接的端点的代码并没有显着地显示问题。
我已经采用了全面的ETW跟踪,但是很多微软提供商都没有合适的文档,这对我很有帮助。
任何解决此问题的建议或关于调整大量传出连接的窗口的建议都会很棒。该平台是Win7(dev)和Win2k8R2(prod)。
答案 0 :(得分:0)
看起来缓慢的DNS查询是罪魁祸首。看看ETW提供商“Microsoft-Windows-Networking-Correlation”,我可以跟踪从开始到连接的网络呼叫,并注意许多连接正在进行> DNS解析器(Microsoft-Windows-RPC)1秒钟。
看起来我们的本地DNS服务器很慢/无法处理我们正在投入的负载而且没有积极地缓存。生产并没有表现出严重的症状,因为prod DNS服务器做的一切都是正确的。