我们有一个应用程序(元搜索引擎),它必须频繁地建立 50 - 250 个出站 HTTP 连接以响应用户操作。
我们这样做的方法是创建一堆 HttpWebRequest 并使用 Action.BeginInvoke 异步运行它们。这显然使用 ThreadPool 来启动 web 请求,这些请求在自己的线程上同步运行。请注意,目前是这种方式,因为它最初是一个 .NET 2.0 应用程序,并且没有 TPL 可言。
使用 ETW(我们的事件源与 .NET 框架和内核事件源相结合)和 NetMon 是,虽然线程池可以在大约 300 毫秒内启动 200 个线程运行我们的代码(因此,这里没有线程池耗尽问题),但它占用的数量是可变的有时,Windows 内核需要 10 - 15 秒才能完成所有已排队的 TCP 连接。
这在 NetMon 中非常明显——您会立即看到大约 60 - 100 个 TCP 连接打开 (SYN)(数量会有所不同,但不会超过 120 个左右),然后其余的会在一段时间内逐渐流入。就好像连接在某个地方排队,但我不知道在哪里,也不知道如何调整它,以便我们可以执行更多并发的传出连接。Perfmon Outbound Connection Queue 保持为 0,但在 Connections established 计数器中,您可以看到连接的初始峰值,然后随着其余的过滤器逐渐增加。
看来我们正在连接的端点的延迟确实起作用,因为在它连接的端点附近运行代码并没有显着显示问题。
我已经进行了全面的 ETW 跟踪,但许多 Microsoft 提供商都没有像样的文档,我敢肯定这会有所帮助。
任何解决此问题的建议或有关为大量传出连接调整窗口的建议都会很棒。该平台是 Win7 (dev) 和 Win2k8R2 (prod)。