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

Ste*_*oat 12 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大约是400ms,由于持续加载,我看不到网站"丢失"他们的缓存并需要再次编译视图.这些页面经常被点击 - 它是一个电子商务商店,我可以看到它经常发生,并在我们最受欢迎的页面上:目录(类别/品牌/性别等)列表和产品详细信息.

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

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

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

Vin*_*nod 4

这是因为 JIT(即时)编译的工作原理。

当您构建应用程序时,它会转换为 .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 应用程序预热模块如何在 IIS 7.5 上预热 ASP.NET MVC 应用程序?,实施分布式缓存等来缓解一些应用程序瓶颈。