为什么ASP经常编译我的视图?

时间:2023-01-16 00:24:23

We have 4 servers load balanced:

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

  • 4 cores @ 2.6Ghz (E5-2650 v2)
  • 4个内核@ 2.6Ghz (e5 - 2650v2)
  • 14GB RAM
  • 14 gb RAM
  • Windows 2012 R2
  • Windows 2012 R2
  • High Performance power setting
  • 高性能电源设置
  • IIS 8.5
  • IIS 8.5
  • ASP 5.3
  • ASP 5.3
  • EF 6.1
  • EF 6.1

They each have a single application pool with one worker process and a single website. Each server has its own copy of the site (DLLs & views), running on a local disk. We are using IIS virtual directories to point to shares on a clustered file server for log files and common images etc (content only). The application pools are set to not shut down when idle (interval of 0) and we have also disabled the every-1740 minute recycle interval too.

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

We have New Relic's .NET agent installed on all servers, and looking through our slow transaction log, I can see that many requests are taking 15 seconds or so to complete. Looking into the trace, I can see a common call to System.Web.Compilation.AssemblyBuilder.Compile() and System.Web.Compilation.BuildManager.CompileWebFile().

我们在所有服务器上都安装了New Relic的. net代理,通过查看我们缓慢的事务日志,我可以看到许多请求需要15秒左右的时间才能完成。查看跟踪,我可以看到对system . web . compile . assembly . build . compile()和system . web . compile . build . manager . compilewebfile()的常见调用。

As far as I know or understand, ASP would compile these views upon first request to them, and cache it (to the temporary ASP files in C:\Windows\Microsoft.Net) and then load from there for subsequent requests.

据我所知或理解,ASP将编译这些观点在第一个请求,并缓存(临时C:\Windows\ ASP文件Microsoft.Net),然后从在后续请求负载。

I'm confused how this is happening so often - when I visit these URLs, the TTFB is about 400ms, and due to constant load I can't see the websites "losing" their cache and needing to compile the views again. These pages are frequently hit - it's an e-commerce store and I can see that it happens often, and on our most popular pages: catalogue (category/brand/gender etc) listings and product details.

我很困惑这是怎么经常发生的——当我访问这些url时,TTFB大约是400ms,由于持续的负载,我无法看到网站“丢失”缓存,需要重新编译视图。这些页面经常被点击——它是一个电子商务商店,我可以看到它经常发生,并且在我们最流行的页面上:目录(类别/品牌/性别等)清单和产品细节。

I've set the settings against each application pool to log an event when recycling, and there have been no events logged when I'm checking the WAS service in the event viewer. We also have New Relic server installed, and looking over the past 6 hours' worth of data, I can't see any dip in RAM usage on any of the servers - which would indicate the application pool recycling. This has really baffled me!

我设置了每个应用程序池的设置,以便在回收时记录事件,并且在检查事件查看器中的WAS服务时没有记录事件。我们还安装了新的Relic服务器,查看了过去6个小时的数据,我看不到任何服务器上的RAM使用率有任何下降——这将表明应用程序池的回收。这真把我难住了!

I'm thinking of moving towards pre-compiling our views as part of our release process - it makes sense really. But it feels like that is working around, or masking an issue which as far as I can see should not be happening. We build our site in Release mode and have <compilation debug="false" /> on all web.config files.

我正在考虑将预编译视图作为发布过程的一部分——它确实有意义。但我觉得这是在作祟,或者掩盖一个我认为不应该发生的问题。我们在发布模式下构建我们的站点,并且在所有web上都有 <编译调试="false" />。配置文件。

Can anyone think of any causes for this?

有人能想到什么原因吗?

1 个解决方案

#1


3  

It is because of how JIT (Just-In-Time) compilation works.

这是因为JIT(即时编译)是如何工作的。

When you build your application, it is converted into .NET Microsoft Intermediate Language (MSIL) or Intermediate Language (IL).

当您构建应用程序时,它被转换为。net Microsoft中间语言(MSIL)或中间语言(IL)。

As your applications is accessed, Common Language Runtime (CLR) converts only executed IL parts of your code into native instructions.

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

Just-In-Time compilation process converts IL to native machine instructions and it is a part of CLR.

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

In a simplified terms when you run a .NET application and your program calls a method. JIT Compiler reads IL from metadata and compiles it into native instructions and run it. Next when your program calls the same method, CLR executes native CPU instructions directly. This process adds some overhead for the first method call. You can go with the other option of pre-compiling your application using NGEN, which is usually not recommended because you will loose some optimizations that only JIT can perform due to its awareness of underlying hardware platform. These two articles has more details http://geekswithblogs.net/ilich/archive/2013/07/09/.net-compilation-part-1.-just-in-time-compiler.aspx and https://msdn.microsoft.com/en-us/library/ms366723.aspx

简单地说,当你运行。net应用程序时,你的程序调用一个方法。JIT编译器从元数据中读取IL并将其编译成本机指令并运行它。接下来,当程序调用相同的方法时,CLR直接执行本地CPU指令。这个过程为第一个方法调用增加了一些开销。您可以使用另一个选项,即使用NGEN预编译应用程序,这通常是不推荐的,因为您将失去一些优化,只有JIT能够执行,这是由于它对底层硬件平台的了解。这两篇文章有更多的细节:http://geekswithblogs.net/ilich/archive/2013/07/09/.net compile -part-1 -just- just-in-time-compiler.aspx和https://msdn.microsoft.com/en-us/library/ms366723.aspx

There are also other things you can try that might help you speed up your application. You can use IIS Application warm up module How to warm up an ASP.NET MVC application on IIS 7.5?, implement distributed caching etc to alleviate some of your application bottlenecks.

您还可以尝试其他方法来帮助您加速应用程序。您可以使用IIS应用程序热身模块如何热身ASP。IIS 7.5上的netmvc应用程序?,实现分布式缓存等,以减轻一些应用程序瓶颈。

#1


3  

It is because of how JIT (Just-In-Time) compilation works.

这是因为JIT(即时编译)是如何工作的。

When you build your application, it is converted into .NET Microsoft Intermediate Language (MSIL) or Intermediate Language (IL).

当您构建应用程序时,它被转换为。net Microsoft中间语言(MSIL)或中间语言(IL)。

As your applications is accessed, Common Language Runtime (CLR) converts only executed IL parts of your code into native instructions.

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

Just-In-Time compilation process converts IL to native machine instructions and it is a part of CLR.

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

In a simplified terms when you run a .NET application and your program calls a method. JIT Compiler reads IL from metadata and compiles it into native instructions and run it. Next when your program calls the same method, CLR executes native CPU instructions directly. This process adds some overhead for the first method call. You can go with the other option of pre-compiling your application using NGEN, which is usually not recommended because you will loose some optimizations that only JIT can perform due to its awareness of underlying hardware platform. These two articles has more details http://geekswithblogs.net/ilich/archive/2013/07/09/.net-compilation-part-1.-just-in-time-compiler.aspx and https://msdn.microsoft.com/en-us/library/ms366723.aspx

简单地说,当你运行。net应用程序时,你的程序调用一个方法。JIT编译器从元数据中读取IL并将其编译成本机指令并运行它。接下来,当程序调用相同的方法时,CLR直接执行本地CPU指令。这个过程为第一个方法调用增加了一些开销。您可以使用另一个选项,即使用NGEN预编译应用程序,这通常是不推荐的,因为您将失去一些优化,只有JIT能够执行,这是由于它对底层硬件平台的了解。这两篇文章有更多的细节:http://geekswithblogs.net/ilich/archive/2013/07/09/.net compile -part-1 -just- just-in-time-compiler.aspx和https://msdn.microsoft.com/en-us/library/ms366723.aspx

There are also other things you can try that might help you speed up your application. You can use IIS Application warm up module How to warm up an ASP.NET MVC application on IIS 7.5?, implement distributed caching etc to alleviate some of your application bottlenecks.

您还可以尝试其他方法来帮助您加速应用程序。您可以使用IIS应用程序热身模块如何热身ASP。IIS 7.5上的netmvc应用程序?,实现分布式缓存等,以减轻一些应用程序瓶颈。