[英]Why is ASP compiling my views so frequently?
We have 4 servers load balanced: 我们有4台服务器负载均衡:
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. 每个服务器都有自己的站点副本(DLL和视图),在本地磁盘上运行。 We are using IIS virtual directories to point to shares on a clustered file server for log files and common images etc (content only). 我们使用IIS虚拟目录指向群集文件服务器上的共享以获取日志文件和常用图像等(仅限内容)。 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. 应用程序池设置为在空闲时不关闭(间隔为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. 我们在所有服务器上安装了New Relic的.NET代理,通过我们的慢速事务日志,我可以看到许多请求需要15秒左右才能完成。 Looking into the trace, I can see a common call to System.Web.Compilation.AssemblyBuilder.Compile()
and System.Web.Compilation.BuildManager.CompileWebFile()
. 查看跟踪,我可以看到对System.Web.Compilation.AssemblyBuilder.Compile()
和System.Web.Compilation.BuildManager.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 \\ Microsoft.Net中的临时ASP文件),然后从那里加载后续请求。
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. 我很困惑这种情况经常发生 - 当我访问这些URL时,TTFB大约是400ms,由于持续加载,我看不到网站“丢失”他们的缓存并需要再次编译视图。 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. 这些页面经常被点击 - 它是一个电子商务商店,我可以看到它经常发生,并在我们最受欢迎的页面上:目录(类别/品牌/性别等)列表和产品详细信息。
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. 我已针对每个应用程序池设置设置以在回收时记录事件,并且在我在事件查看器中检查WAS服务时未记录任何事件。 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. 我们还安装了New Relic服务器,并查看过去6小时的数据,我看不到任何服务器上的RAM使用量下降 - 这表明应用程序池的回收。 This has really baffled me! 这真让我困惑!
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.config
文件上都有<compilation debug="false" />
。
Can anyone think of any causes for this? 任何人都可以想到这个的原因吗?
It is because of how JIT (Just-In-Time) compilation works. 这是因为JIT(Just-In-Time)编译的工作原理。
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. 简而言之,当您运行.NET应用程序并且程序调用方法时。 JIT Compiler reads IL from metadata and compiles it into native instructions and run it. JIT编译器从元数据中读取IL并将其编译为本机指令并运行它。 Next when your program calls the same method, CLR executes native CPU instructions directly. 接下来,当您的程序调用相同的方法时,CLR直接执行本机CPU指令。 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. 您可以使用NGEN预编译应用程序的其他选项,这通常不建议使用,因为您将失去一些只有JIT可以执行的优化,因为它对底层硬件平台有所了解。 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 这两篇文章有更多细节http://geekswithblogs.net/ilich/archive/2013/07/09/.net-compilation-part-1.-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? 您可以使用IIS应用程序预热模块如何在IIS 7.5上预热ASP.NET MVC应用程序? , implement distributed caching etc to alleviate some of your application bottlenecks. ,实现分布式缓存等,以缓解您的一些应用程序瓶颈。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.