修复IIS的缓慢的初始负载

对于低stream量的网站,IIS有一个令人讨厌的function,它可以循环使用未使用的工作进程,并在一段时间后让第一个用户访问该网站,以获得非常长的延迟(30多秒)。

我一直在寻找解决这个问题的方法,并find了这些潜在的解决scheme。

A. 使用应用程序初始化插件

B. 使用.NET 4自动启动

C. 禁用空闲超时(在IIS重置下)

D. 预编译该网站

我想知道哪个更受欢迎,更重要的是,为什么会有这么多的解决scheme来解决这个问题? (我的猜测是他们不是,我只是不正确的理解东西)。

编辑

执行C似乎足以让我的网站保持温暖,但我发现,我的网站缓慢的真正根源与entity framework,我似乎无法弄清楚为什么它会变冷。 看到这个问题, 遗憾的是还没有得到回答 ,已经回答了!

我最终只是做一个温暖的脚本 ,偶尔打我的网站,以确保它保持快速。

选项A,B和D似乎属于同一类别,因为它们只影响最初的开始时间,它们会对网站进行热身,如编译和加载内存中的库。

使用C,设置空闲超时应该足够,以便后续对服务器的请求得到快速服务(重新启动应用程序池需要相当长的时间 – 大约为几秒钟)。

据我所知,超时存在,以节省该机器上并行运行的其他网站可能需要的内存。 价格是一次慢加载时间。

除了应用程序池在用户不活动的情况下closures应用程序池,应用程序池也将默认每1740分钟(29小时)回收。

来自technet:

Internet信息服务(IIS)应用程序池可定期回收,以避免可能导致应用程序崩溃,挂起或内存泄漏的不稳定状态。

只要应用程序池回收剩下,应该就够了。 但是,如果你真的想要大多数组件的顶尖性能,你也应该使用像你提到的应用程序初始化模块。

虚拟主机挑战

您必须记住,如果我们中的许多人(小公司和个人)都在共享服务器上托pipe,则没有任何计算机configuration选项可用。

ASP.NET MVC开销

当我的网站在20分钟内没有被击中时,我的网站至less需要30秒(而networking应用程序已经停止)。 这很糟糕。

另一种testing性能的方法

还有另一种方法来testing它是否是您的ASP.NET MVC启动或其他。 在您的网站上放置一个正常的HTML页面,您可以直接点击它。
如果问题与ASP.NET MVC启动相关,那么即使Web应用程序尚未启动,HTML页面也将立即渲染。
这就是我第一次意识到这个问题是在ASP.NET MVC的启动。 我随时加载了一个HTML页面,它会快速加载。 然后,击中该HTML页面后,我打了我的一个ASP.NET MVCurl,我会得到Chrome消息“等待raddev.us …”

另一个testing与有用的脚本

之后,我写了一个LINQPad(查看更多http://linqpad.net )脚本,每隔8分钟就会打我的网站(比应用程序卸载的时间less20分钟),我让它运行几个小时。

当脚本运行时,我打了我的网站,每次我的网站出现得非常快。 这给了我一个很好的想法,很可能我遇到的缓慢是由于ASP.NET MVC的启动时间。

获取LinqPad,你可以运行下面的脚本 – 只需要改变你自己的URL,让它运行,你可以很容易地testing。 祝你好运。

注意 :在LinqPad中,您需要按F4并添加对System.Net的引用以添加将检索您的页面的库。

另外 :确保你改变string的URLvariables,指向一个URL,将从您的ASP.NET MVC网站加载一个路由,引擎将运行。

System.Timers.Timer webKeepAlive = new System.Timers.Timer(); Int64 counter = 0; void Main() { webKeepAlive.Interval = 5000; webKeepAlive.Elapsed += WebKeepAlive_Elapsed; webKeepAlive.Start(); } private void WebKeepAlive_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { webKeepAlive.Stop(); try { // ONLY the first time it retrieves the content it will print the string String finalHtml = GetWebContent(); if (counter < 1) { Console.WriteLine(finalHtml); } counter++; } finally { webKeepAlive.Interval = 480000; // every 8 minutes webKeepAlive.Start(); } } public String GetWebContent() { try { String URL = "http://YOURURL.COM"; WebRequest request = WebRequest.Create(URL); WebResponse response = request.GetResponse(); Stream data = response.GetResponseStream(); string html = String.Empty; using (StreamReader sr = new StreamReader(data)) { html = sr.ReadToEnd(); } Console.WriteLine (String.Format("{0} : success",DateTime.Now)); return html; } catch (Exception ex) { Console.WriteLine (String.Format("{0} -- GetWebContent() : {1}",DateTime.Now,ex.Message)); return "fail"; } } 

我会使用B,因为与工作stream程回收相结合意味着只有在回收时才会有延迟。 这避免了在空闲之后通常与响应于第一请求的初始化相关联的延迟。 你也可以保持回收的好处。

写一个ping服务/脚本来打你闲置的网站是相当好的方法,因为你将拥有一个完整的控制。 如果您已经租用专用的托pipe框,您提到的其他选项将可用。

在共享主机空间中,热身脚本是最好的一级防御(自助是最好的帮助)。 这里是一篇文章,分享如何从您自己的Web应用程序做到这一点的想法 。

请参阅本文以获取有关如何帮助解决性能问题的提示。 这包括在“冷启动”部分中涉及启动的性能问题。 无论您在本地还是在生产中使用的服务器types多半都是如此。

http://blogs.msdn.com/b/mcsuksoldev/archive/2011/01/19/common-performance-issues-on-asp-net-web-sites.aspx

如果应用程序从XML(包括Web服务…)反序列化任何内容,请确保SGEN针对所有涉及deseriaization的二进制文件运行,并将生成的dll放在全局程序集caching(GAC)中。 这预编译了SGEN运行的程序集所使用的所有序列化对象,并将它们caching在生成的DLL中。 这可以节省大量的时间,从磁盘的第一次反序列化(加载)configuration文件和初始调用Web服务。 http://msdn.microsoft.com/en-us/library/bk3w6240(VS.80).aspx

如果有任何IIS服务器不具有对Internet的传出访问权限,请通过在machine.config中添加generatePublisherEvidence =“false”来closures对Authenticode二进制文件的证书撤消列表(CRL)检查。 否则,在启动过程中,每个工作进程可能会挂起超过20秒,而超时尝试连接到Internet以获取CRL列表。 http://blogs.msdn.com/amolravande/archive/2008/07/20/startup-performance-disable-the-generatepublisherevidence-property.aspx

http://msdn.microsoft.com/en-us/library/bb629393.aspx

考虑在所有组件上使用NGEN。 但是,如果不小心使用,这并不会带来很大的性能提升。 这是因为每个进程加载的所有二进制文件的基本加载地址必须在构build时仔细设置,以避免重叠。 如果由于地址冲突而导致二进制文件被重新加载时,几乎所有使用NGEN的性能收益都将丢失。 http://msdn.microsoft.com/en-us/magazine/cc163610.aspx

按时间表对网站进行ping命令的一个很好的select是使用Microsoft Flow,每个月最多可免费使用750个“运行”。 创build一个Flow,每小时点击一次您的站点以保持它的温度非常容易。 你甚至可以通过创build一个单一的stream程来解决750的限制,延迟时间会将网站的多个命中分开。

https://flow.microsoft.com