c# - Windows 内核排队出站网络连接

标签 c# windows performance networking tcp

我们有一个应用程序(元搜索引擎)必须经常建立 50 - 250 个出站 HTTP 连接以响应用户操作。

我们这样做的方法是创建一堆 HttpWebRequest 并使用 Action.BeginInvoke 异步运行它们。这显然使用 ThreadPool 来启动 Web 请求,这些请求在自己的线程上同步运行。请注意,目前是这种方式,因为这最初是一个 .NET 2.0 应用程序,没有 TPL 可言。

使用 ETW(我们的事件源与 .NET 框架和内核事件源相结合)和 NetMon 是,虽然线程池可以在大约 300 毫秒内启动 200 个线程来运行我们的代码(因此,这里没有线程池耗尽问题),但它占用Windows 内核建立所有已排队的 TCP 连接的时间长短不定,有时长达 10 - 15 秒。

这在 NetMon 中非常明显 - 您会看到大约 60 - 100 个 TCP 连接立即打开 (SYN)(数量会有所不同,但绝不会超过 120 个左右),然后其余的会在一段时间内逐渐加入。就好像连接在某处排队,但我不知道在哪里,也不知道如何调整它,以便我们可以执行更多并发传出连接。 Perfmon Outbound Connection Queue 保持为 0,但在 Connections Established 计数器中,您可以看到连接的初始峰值,然后随着其余连接的过滤而逐渐增加。

我们连接的端点的延迟似乎确实起到了一定的作用,因为在它连接的端点附近运行代码并没有显着显示问题。

我已经进行了全面的 ETW 跟踪,但没有关于许多 Microsoft 提供商的合适文档,我相信这会有所帮助。

解决此问题的任何建议或针对大量传出连接调整窗口的建议都很棒。平台为 Win7 (dev) 和 Win2k8R2 (prod)。

最佳答案

看起来缓慢的 DNS 查询是这里的罪魁祸首。查看 ETW 提供程序“Microsoft-Windows-Networking-Correlation”,我可以跟踪从开始到连接的网络调用,并注意到许多连接在 DNS 解析器 (Microsoft-Windows-RPC) 上花费的时间 > 1 秒。

我们的本地 DNS 服务器似乎很慢/无法处理我们施加给它的负载并且没有积极缓存。生产并没有表现出像 prod DNS 服务器那样严重的症状,一切正常。

关于c# - Windows 内核排队出站网络连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16660636/

相关文章:

C# 等效于 Swift typealias

c# - 为什么我的 2 个向量角度函数返回 NaN,即使我遵循公式

c# - 启动 Windows 服务并启动 cmd

Windows批处理文件从文件名中提取编号

c# - 忽略 ASP.NET Identity 中静态文件的身份验证

c# - TempData 未被清除

c# - 为什么我的 "yield"不工作?

c++ - 将 FILE * 或 HANDLE 转换(分配)到 Windows 中的 IStream

java - 并行冒泡排序性能

java - 在Java中实现enqueue的更有效的方法是什么