2016-11-22 68 views
10

我们有4台服务器进行负载平衡:为什么ASP如此频繁地编译我的视图?

  • 4核2.6GHz的@(E5-2650 V2)
  • 14GB RAM
  • 的Windows 2012 R2
  • 高性能功率设置
  • IIS 8.5
  • ASP 5.3
  • EF 6.1

它们每个都有一个应用程序池,只有一个工作进程和一个网站。每个服务器都有自己的本地副本(DLLs &视图),在本地磁盘上运行。我们使用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使用率都没有下降 - 这将表明应用程序池回收。这让我很困惑!

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

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

+0

您是如何得出System.Web.Compilation.AssemblyBuilder.Compile()和System.Web.Compilation.BuildManager.CompileWebFile()消耗大部分15秒延迟的结论的?只是想知道延迟是否在别的地方。您是否试图捕获操作方法收到请求后花费了多少时间?发起http请求的客户端与服务器之间的网络延迟如何? – Vinod

+0

我正在使用New Relic来查看'slow transactions',并且我们所有的慢事务都包含对这些方法的调用,并且占用了15%的页面请求。当我在网站上开发时,我看到了类似的效果 - 当我重建项目并重新加载页面时,渲染需要很长时间(搁置应用程序启动时间)。如果我然后访问另一个控制器上的页面,那么显示的“减速”与再次刷新页面(而视图是第一次渲染) –

+0

不试图偏离实际主题,但大多数应用程序最近一直在使用asp.net mvc,我正在将他们推向单页应用程序架构。可能不是纯粹的SPA,我仍然有多个观点,但很少。这种设计可以帮助我避免您面临的问题。它在客户端引入了复杂性,但更好的用户体验。 – Vinod

回答

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?,实施分布式缓存等来缓解您的某些应用程序瓶颈。

+0

嗨,感谢您的答案 - 但我确实看到\t System.Web.Compilation.BuildManager.CompileWebFile()经常被调用 - 在MVC控制器上至少会收到1 /秒的请求。我认为所有的“热点”在应用程序的运行时间期间会频繁发生(我们认为应用程序池上次回收后大约需要5个小时)吗? –