为什么ASP频繁编译我的观点?

时间:2016-11-22 21:17:21

标签: asp.net asp.net-mvc razor newrelic

我们有4台服务器负载均衡:

  • 4核@ 2.6Ghz(E5-2650 v2)
  • 14GB RAM
  • Windows 2012 R2
  • 高性能电源设置
  • IIS 8.5
  • ASP 5.3
  • EF 6.1

它们每个都有一个应用程序池,其中包含一个工作进程和一个网站。每个服务器都有自己的站点副本(DLL和视图),在本地磁盘上运行。我们使用IIS虚拟目录指向群集文件服务器上的共享以获取日志文件和常用图像等(仅限内容)。应用程序池设置为在空闲时不关闭(间隔为0),并且我们也禁用了每1740分钟的循环间隔。

我们在所有服务器上都安装了New Relic的.NET代理,通过我们的慢速事务日志,我可以看到许多请求需要15秒左右才能完成。通过查看跟踪,我可以看到对System.Web.Compilation.AssemblyBuilder.Compile()System.Web.Compilation.BuildManager.CompileWebFile()的常见通话。

据我所知或理解,ASP会在第一次请求时编译这些视图,并将其缓存(到C:\ Windows \ Microsoft.Net中的临时ASP文件),然后从那里加载后续请求。

我很困惑这种情况经常发生 - 当我访问这些URL时,TTFB约为400毫秒,由于持续加载,我无法看到网站“丢失”其缓存并需要再次编译视图。这些页面经常被点击 - 它是一个电子商务商店,我可以看到它经常发生,并且在我们最受欢迎的页面上:目录(类别/品牌/性别等)列表和产品详细信息。

我已针对每个应用程序池设置设置以在回收时记录事件,并且在我在事件查看器中检查WAS服务时未记录任何事件。我们还安装了New Relic服务器,并查看过去6小时的数据,我看不到任何服务器上的RAM使用量下降 - 这表明应用程序池的回收。这真令我困惑!

我正在考虑将我们的观点作为发布过程的一部分进行预编译 - 这真的很有意义。但感觉就像是在解决这个问题,或者掩盖一个我认为不应该发生的问题。我们以发布模式构建我们的网站,并在所有<compilation debug="false" />个文件上web.config

任何人都可以想到这个的原因吗?

1 个答案:

答案 0 :(得分:3)

这是因为JIT(Just-In-Time)编译的工作原理。

构建应用程序时,它将转换为.NET Microsoft中间语言(MSIL)或中间语言(IL)。

在访问您的应用程序时,公共语言运行时(CLR)仅将代码的已执行IL部分转换为本机指令。

即时编译过程将IL转换为本机机器指令,它是CLR的一部分。

以简化的术语表示运行.NET应用程序并且程序调用方法时。 JIT编译器从元数据中读取IL并将其编译为本机指令并运行它。接下来,当您的程序调用相同的方法时,CLR直接执行本机CPU指令。此过程为第一个方法调用增加了一些开销。您可以使用NGEN预编译应用程序的其他选项,这通常不建议使用,因为您将失去一些只有JIT可以执行的优化,因为它对底层硬件平台有所了解。这两篇文章有更多细节 http://geekswithblogs.net/ilich/archive/2013/07/09/.net-compilation-part-1.-just-in-time-compiler.aspxhttps://msdn.microsoft.com/en-us/library/ms366723.aspx

您还可以尝试其他可以帮助您加快应用程序的事情。您可以使用IIS应用程序预热模块How to warm up an ASP.NET MVC application on IIS 7.5?,实现分布式缓存等,以缓解您的一些应用程序瓶颈。