有没有办法检测尝试出站连接何时排队?
我们的ASP.NET应用程序向其他Web服务发出大量的出站请求。最近我们遇到了主要的性能问题,其中对特定端点的调用需要很长时间才能完成或超时。该服务的所有者未发现任何性能问题。当我们分析网络流量时,我们确实看到了HTTP请求确实及时完成。那时我们发现我们漫长的等待时间和超时是由于连接排队造成的。
我们解决此问题的第一种方法是简单地增加到该端点的允许出站连接数量,因此:
<system.net>
<connectionManagement>
<add address="http://some.endpoint.com" maxconnection="96" />
</connectionManagement>
</system.net>
这确实放弃了我们对端点的调用。但是,我们注意到这导致我们的整体入站请求需要更长时间才能完成。那是我们遇到Microsoft KB 821268的时候。遵循“经验法则”指南,我们提出了这些额外的更改:
<processModel maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50"/>
<httpRuntime minFreeThreads="704" minLocalRequestFreeThreads="608"/>
这似乎可以修复所有内容。我们对some.endpoint.com
的调用仍然很快,我们的响应时间也下降了。
然而,几天后,我们注意到我们的网站性能不佳,我们看到了一些SQL Server超时。我们的DBA没有看到服务器性能有任何不妥,所以这看起来像是类似的事情再次发生;我们想知道增加到some.endpoint.com
的连接是否导致其他出站呼叫到队列,可能是由于线程不足。
最糟糕的是,我们还没有找到一个很好的技术来明确地知道是否正在进行出站连接排队。我们所能做的就是观察我们提出请求和在申请中收到回复之间的时间。很难知道超时和长响应时间是否是由于专门排队造成的。
是否有任何有效的工具来衡量和调整出站请求限制?任何其他性能调优技巧也一定会受到赞赏。
答案 0 :(得分:6)
您所描述的问题涉及许多诊断领域,我认为没有一个简单的工具可以让您说出您是否遭受过争用。从您的描述中看起来就像耗尽了连接或线程池。这通常涉及线程锁定。除了@Simon Mourier指出的HttpWebRequest Average Queue Time
效果计数器(记得在config file中设置performancecounters="enabled"
),还有更多需要监控的内容。我将从监视ASP.NET应用程序中的线程池使用情况的自定义性能计数器开始 - 遗憾的是它们不包含在框架计数器中,但它们实现起来非常简单,如图所示here。另外,我编写了一个简单的PowerShell脚本,它将为您的应用程序中的线程状态分组。你可以从here得到它。它类似于Linux中的顶级命令,它将向您显示进程的线程状态或线程等待原因。看看2个应用程序(都命名为Program.exe)截图:
遭受争用的人
> .\ThreadsTop.ps1 -ThreadStates -ProcMask Program
Threads states / process
Process Name Initialized Ready Running Standby Terminated Waiting Transition Unknown
------------ ----------- ----- ------- ------- ---------- ------- ---------- -------
Program 0 0 0 0 0 22 0 0
等待线程数不断增长
> .\ThreadsTop.ps1 -ThreadWaitReasons -ProcMask Program
Legend:
0 - Waiting for a component of the Windows NT Executive| 1 - Waiting for a page to be freed
2 - Waiting for a page to be mapped or copied | 3 - Waiting for space to be allocated in the paged or nonpag
ed pool
4 - Waiting for an Execution Delay to be resolved | 5 - Suspended
6 - Waiting for a user request | 7 - Waiting for a component of the Windows NT Executive
8 - Waiting for a page to be freed | 9 - Waiting for a page to be mapped or copied
10 - Waiting for space to be allocated in the paged or nonpaged pool| 11 - Waiting for an Execution Delay to be resolve
d
12 - Suspended | 13 - Waiting for a user request
14 - Waiting for an event pair high | 15 - Waiting for an event pair low
16 - Waiting for an LPC Receive notice | 17 - Waiting for an LPC Reply notice
18 - Waiting for virtual memory to be allocated | 19 - Waiting for a page to be written to disk
Process Name 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
------------ - - - - - - - - - - -- -- -- -- -- -- -- -- -- --
Program 1 0 0 0 0 0 34 0 0 0 0 0 0 0 0 3 0 0 0 0
和其他正常运行:
> .\ThreadsTop.ps1 -ThreadStates -ProcMask Program
Threads states / process
Process Name Initialized Ready Running Standby Terminated Waiting Transition Unknown
------------ ----------- ----- ------- ------- ---------- ------- ---------- -------
Program 0 1 6 0 0 20 0 0
等待线程的数量不会超过24。
> .\ThreadsTop.ps1 -ThreadWaitReasons -ProcMask Program
Legend:
0 - Waiting for a component of the Windows NT Executive| 1 - Waiting for a page to be freed
2 - Waiting for a page to be mapped or copied | 3 - Waiting for space to be allocated in the paged or nonpag
ed pool
4 - Waiting for an Execution Delay to be resolved | 5 - Suspended
6 - Waiting for a user request | 7 - Waiting for a component of the Windows NT Executive
8 - Waiting for a page to be freed | 9 - Waiting for a page to be mapped or copied
10 - Waiting for space to be allocated in the paged or nonpaged pool| 11 - Waiting for an Execution Delay to be resolve
d
12 - Suspended | 13 - Waiting for a user request
14 - Waiting for an event pair high | 15 - Waiting for an event pair low
16 - Waiting for an LPC Receive notice | 17 - Waiting for an LPC Reply notice
18 - Waiting for virtual memory to be allocated | 19 - Waiting for a page to be written to disk
Process Name 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
------------ - - - - - - - - - - -- -- -- -- -- -- -- -- -- --
Program 1 0 0 0 0 0 18 0 0 0 0 0 0 0 0 6 0 0 0 0
当然,在你的情况下,线程的数量会高得多,但是你应该能够在平静的时间内观察线程行为的一些趋势。当您遭遇争用时,等待队列达到峰值。
您可以自由修改我的脚本,以便将此数据转储到除控制台之外的其他位置(如数据库)。最后,我建议运行Concurrency Visualizer等分析器,这样可以更深入地了解应用程序中的线程行为。启用system.net trace sources也可能有所帮助,尽管事件的数量可能非常大,因此请尝试相应地调整它。
答案 1 :(得分:0)
Nagling是发送方的TCP优化,旨在实现 通过将小发送请求合并到网络中来减少网络拥塞 更大的TCP段。这是通过阻止小段来实现的 或者直到TCP有足够的数据来传输完整大小的段或 直到所有未完成的数据都被接收方确认
然而,Nagling与TCP延迟ACK(TCP)的交互性很差 接收器的优化。它旨在减少数量 通过短时间延迟ACK确认数据包。 RFC 1122 说延迟不应超过500毫秒,应该 是每个第二段的ACK。由于接收器延迟ACK 并且发送方在发送小段之前等待ACK, 数据传输可能会停止,直到延迟的ACK到达。
来源here
看起来你的服务器非常“烦乱”,一直在发出大量的请求和响应,试试这个:
ServicePointManager.UseNagleAlgorithm = false;
答案 2 :(得分:0)
你在这里描述的是一个非常复杂的问题。您的应用程序基本上处于其他几个方面,SQL Server,Web服务提供商等,您正试图弄清楚什么是缓慢的。是你的应用程序还是你所依赖的其他人。
我已经走上了试图设置性能监视器和挖掘日志等的道路,但发现它非常耗时且难以可视化一段时间内实际发生的事情。收集数据和查看某个时间点很容易。很难看到所有数据并使其在一段时间内变得有意义,特别是如果涉及很多连接系统的话。
如果我是你,我会尝试免费的NewRelic试用版:http://newrelic.com/application-monitoring我之前使用过他们的产品,发现它对这类问题非常宝贵。