当对我的 Web 服务器和数据库服务器之间的流量进行 TCP 分析时,我发现网络缓冲区(TCP 窗口)经常被填满。然后,Web 服务器向数据库服务器发送 TCP 消息,告知其缓冲区已满,并且在更新之前不要发送更多数据。
例如,这是随着时间的推移与数据库服务器的寿命较长的连接之一的网络缓冲区的大小(以字节为单位):
Web 服务器正在 Windows 2008 R2 Web 服务器上运行以 IIS 集成模式运行的 .NET 4.0 应用程序。 SQL 服务器是 2008 R2 服务器。
我对此的解释是,SQL 服务器将数据返回到 Web 服务器的速度比 Web 服务器上的应用程序从缓冲区收集数据的速度更快。我已尝试调整网络驱动程序中的所有内容来解决此问题。特别是增加 RSS 队列、禁用中断调节以及设置 Windows 2008 R2 服务器以更积极地增加缓冲区大小。
因此,如果我的解释是正确的,那么我想知道两种可能性:
- .NET 中有什么方法可以告诉它增加网络缓冲区的大小吗? “增强型 2008 R2 TCP 堆栈”很少决定为此连接启用窗口缩放(使缓冲区大于 65 kBytes)(可能是由于低延迟)。看起来在 Windows Server 2008 r2 中手动设置此系统范围的功能已消失(曾经有注册表项,现在已被忽略)。那么有没有办法可以在代码中强制执行此操作?
- 是否可以进行任何调整来加快应用程序读取网络缓冲区信息的速度,特别是 SQL 连接的速度?
Edit:
请求的 DMV 查询在 ASYNC_NETWORK_IO 处中断:
SELECT * FROM sys.dm_os_wait_stats ORDER BY waiting_tasks_count desc;
wait_type waiting_tasks_count wait_time_ms max_wait_time_ms signal_wait_time_ms
CXPACKET 1436226309 2772827343 39259 354295135
SLEEP_TASK 231661274 337253925 10808 71665032
LATCH_EX 214958564 894509148 11855 84816450
SOS_SCHEDULER_YIELD 176997645 227440530 2997 227332659
ASYNC_NETWORK_IO 112914243 84132232 16707 16250951
1) 是什么让您认为这是 TCP 流量控制,而不是 SQL Server 在没有流量的时间间隔内不生成数据?检查是否sys.dm_exec_requests
查看 wait_type。等待类型的描述见等待和队列 http://msdn.microsoft.com/en-us/library/cc966413.aspx。如果确实是客户端应用 TCP 流量控制,那么您将看到等待类型ASYNC_NETWORK_IO
.
2) If问题确实是网络等待类型,那么解决方案不是增加带宽,而是明显减少流量。客户端没有业务向服务器请求如此多的数据以引起 TCP 流量控制。这可能是由于在客户端中执行了严重错误的操作而导致的,例如计算行数或客户端分页。将处理移至服务器上,只需获取包含所需数据的小型结果集。
Edit
使用数据库调用结果集最终归结为以下一种形式:
FetchNextRow
while (not EnfOfResults)
{
ProcessRow;
FetchNextRow;
}
这可能意味着什么,实际上,它可能是foreach row in IQueryable
or SqlDataReader.Read()
。但基本思想是相同的,即客户端从结果中获取行,处理它们,然后获取更多行。如果客户端代码这样做anything在那里面ProcessRow
阻塞,那么客户端代码将无法到达再次获取下一行的位置,因此最终将触发 TCP 流控制,这反过来将导致 SQL Server 挂起查询(因为它没有地方将结果写入)。对于 TCP 而言,您无法采取任何措施来改善这一情况。增加窗口大小实际上会使情况变得更糟,因为现在所有那些以前在源(DB)处被抑制的结果都将被创建并必须存储在某个地方,这最终意味着将实时内存分配给存储并可能使事情变得更糟比他们现在更糟糕。
如果我现在处于你的处境,我会专注于识别where这样做ProcessRow
发生阻塞。我提出的一个假设是,该处理将是一个 MVC 视图写入响应缓冲区,并依次被 TCP 流控制阻止,这是由于用户代理不消耗 HTTP 响应(例如,Ajax 调用已完成但浏览器未运行)消耗响应的完成代码,因为主线程正在循环忙于其他事情)。与往常一样,最好的方法是有条不紊地进行衡量。一些可能的工具:
- Look at ASP.Net 性能计数器 http://msdn.microsoft.com/en-us/library/fxk122b4.aspx.
- 使用您自己的性能计数器来检测您的代码(比大多数开发人员想象的要容易得多,请参阅使用 XSLT 生成性能计数器代码 http://rusanu.com/2009/04/11/using-xslt-to-generate-performance-counters-code/)
- 非侵入式采样性能轨迹,请参阅使用 VSPerfASPNETCmd 进行快速网站分析 http://msdn.microsoft.com/en-us/library/ee308442.aspx
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)