什么在ASP.NET应用程序中消耗超过65%的时间?

时间:2011-08-11 05:53:38

标签: asp.net asp.net-mvc performance visual-studio-2010 iis-7.5

我有一个托管在Windows 7 / IIS 7.5上的.Net Framework 4.0,ASP.NET,ASP.NET MVC 3 Web应用程序。在此计算机上启用IIS日志记录并设置为以W3C模式登录。

使用Release配置编译应用程序,并将其部署到IIS,并明确设置<compilation debug='false'属性。 Web.config指定使用基于SQL Server的会话状态。

我分别在BeginRequest和EndRequest事件中的Global.asax中添加了以下语句。结果即“sw.Elapsed.TotalMilliseconds”将存储在应用程序级别的值列表中。我通过调试页面转储这些值并获得相同的平均值。

// in BeginRequest
HttpContext.Current.Items.Add("RequestStartEnd", System.Diagnostics.Stopwatch.StartNew());

// in EndRequest
var sw = (System.Diagnostics.Stopwatch)HttpContext.Current.Items["RequestStartEnd"];
sw.Stop();

我创建了一个负载测试,它针对此应用程序运行单个请求,并发用20个用户的用户负载。该测试在Visual Studio 2010 Ultimate Edition中运行。

在运行负载测试后,我得到了秒表记录的平均时间为681毫秒。这些请求的每个IIS的平均时间(我在运行负载测试之前清除了所有日志)是2121毫秒。 IIS的平均时间与Visual Studio负载测试报告中显示的值相符。

秒表时间仅占IIS日志/ Visual Studio报告的时间的32%。其他68%的时间去哪儿了?

更新1: 我将会话状态设置为InProc并重新运行负载测试。在这种情况下,秒表报告的平均时间与IIS日志报告的平均时间之间的差异增长到70%以上!那段时间一直在哪里?

更新2: @Peter - 我通过放置跟踪规则来登录状态代码200来尝试失败的请求跟踪。接下来,我用20个并发用户运行负载测试大约1.5分钟。经过最后50个跟踪文件,发现该报告中的“Time Taken”字段的范围为750ms到1300ms。 Visual Studio报告显示平均值。时间为2300ms。在报告中,使用紧凑视图,我看到所需的时间在以下转换之间发生变化     (1)AspNetStart - &gt; AspNetAppDomainEnter     (2)ManagedPipelineHandler-start ManagedPipelineHandler-end。 (2)项可能是我的应用程序代码。仍然存在根据失败的请求日志(即1300ms)和平均值所花费的最大时间之间的巨大差异。时间如Visual Studio 2300ms所示。如何找到会计?感谢这个伟大的提示!

5 个答案:

答案 0 :(得分:3)

您运行负载测试需要多长时间?如果您在Windows 7下运行它,您可能会得到与Windows服务器不同的结果。您可能遇到在突发加载下将线程分配给线程池的问题。 .Net将立即将线程分配到线程池min,然后慢慢分配到线程池max。我相信客户端操作系统的默认设置与服务器操作系统的默认设置不同。它可能在客户端操作系统上,默认的最小线程设置等于您机器上的核心数,这意味着.net将慢慢分配更多线程以满足您的突发负载。

一个简单的检查是让你的负载测试运行更长时间,看看你的两次测量之间的差距是否缩小。

答案 1 :(得分:2)

通过使用“失败的请求跟踪规则”,可以更好地查看应用程序的内部结构

http://learn.iis.net/page.aspx/266/troubleshooting-failed-requests-using-tracing-in-iis-7/

通过它,您可以完全按照您的应用程序在IIS中执行的操作

答案 2 :(得分:2)

我建议调查MvcMiniProfiler。这是一个NuGet包你可以添加和连接(几乎毫不费力),真正打破你的MVC应用程序中各点的执行时间。您可以看到每个请求的实时视图以及任何瓶颈所在的位置。

更多信息:

答案 3 :(得分:2)

最有可能是 托管渠道 开销和 网络 (甚至是localhost或127.0)的组合。 0.1)可能是可以解释“丢失”时间的地方。

  1. 您提到IIS日志与您的Visual Studio加载相符 测试数据 - 两者都涉及网络堆栈和管理的pipleline。
  2. 你的秒表代码只在ASP.NET上下文中执行(只是 在ASP.NET执行开始之前和它结束之前),并没有考虑到 处理TCP网络请求的IIS开销,解析 请求和响应以及传输时间的HTTP标头 通过托管管道和TCP堆栈。
  3. [编辑] 如果您的ASP.NET页面执行时间非常快,则该比例会被夸大,例如:相对于TCP堆栈的其余部分以及为您整理HTTP请求的托管管道,它不会占用大量CPU

答案 4 :(得分:1)

如果您遇到长时间加载的问题,如果您有大量的IO操作,它可能会影响到这一点 如果你正在使用orm进行数据库查询尝试使用sql profiler在vs中分析你的sql语句,或者在profiler中内置的sql server中分析sql语句,如果你得到很多单独的查询,你可能要考虑使用linq查询中的一些包含来捆绑将您的部分数据转换为单个查询

如果你有很多IO操作,你可能还想考虑使用异步控制器来改善响应时间,这样你的应用程序就不会等待每个io操作完成 见wintellect.com/CS/blogs/jprosise/archive/2010/03/29/…

还有比iis日志记录更好的日志记录解决方案,因为它是一个相当古老的组件,您可能需要查看log4net以获取更一般的日志记录,或者elmah用于记录错误和异常,因为这些解决方案可以捆绑一堆日志条目和在单个操作中写入几个也提高了IO性能