ASP.NET MVC:在几分钟后首先访问缓慢,然后每个后续请求都很快

时间:2010-07-30 17:34:57

标签: asp.net asp.net-mvc iis iis-7

当我第一次访问我的ASP.NET MVC网站的任何页面时,第一次请求很慢。加载需要大约4-5秒。但是,对任何页面的每个后续请求都很快。

当我等待几分钟或一小时后,每次第一次请求再次变慢。以下每个请求都很快。

我认为IIS 7正在编译代码并将其保存在内存中。一段时间后,它会将其从内存中删除,因此需要再次编译它。

我可以做的是,每个第一个请求的速度与以后的每个请求一样快吗? (如果可能的话,不预编译我的源代码)

非常感谢你!

5 个答案:

答案 0 :(得分:21)

如果这是生产服务器,那么为什么不尝试添加网站监视器;例如up time robot。它基本上要求您的网站标题,并每隔5分钟获取“200-ok”,“404-not found”等状态代码。这样,您的站点始终会启动,并且不会影响日志文件/分析,因为只需要标头。我将它用于我的云站点,因为我发现它们需要5秒才能启动,这会对站点加载产生影响。使用显示器,它们是即时的。

哦,它最多可以免费使用50个网站!

答案 1 :(得分:17)

这可能是应用程序池上的回收工作进程设置,检查其值,并将其关闭或延长。

在应用程序池的性能空闲后,也可以是关闭工作进程。

这可能是第二次,默认为20分钟,第一次默认为29小时,我相信。

答案 2 :(得分:5)

这几乎可以肯定是你的应用程序池空闲超时设置(而不是你的代码被重新编译)。

IIS中的默认应用程序池空闲超时为20分钟。这意味着,如果20分钟过去且没有请求进入您的应用程序,IIS将关闭您的应用程序池的工作进程,使您的应用程序“冷”#34;再次。当IIS重新启动工作进程并且#34;温暖"你的应用备份。

如果您不希望IIS自动"冷却"在一段时间不活动后,您的应用可以通过将应用池空闲超时设置为0来禁用它。

答案 3 :(得分:1)

假设您有常规的访问者流,这在生产中不应该是一个问题。此外,除非您在物理上更改任何源文件,否则IIS在旋转您的应用程序时不会重新编译它。

另外,请查看可用的.NET编译设置: http://technet.microsoft.com/en-us/library/cc725812(WS.10).aspx

答案 4 :(得分:0)

<强> TL;医生

经过相当广泛的测试和收集相关来源以尝试解决问题后,我认为最小的解决方案可能(未经验证)将此代码添加到global.asax:

    protected void Application_End()
    {
        ...
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://web_domain.tld");
        using (HttpWebResponse response = (HttpWebResponse)
            request.GetResponse())
        {
        }
        ...
    }

在撰写帖子时,这用于有效地维护我在“永远向上”工作的网站 - 并将IIS中的Idle Time-out (minutes)设置为0,如其他答案中所述。 但是我认为可能没有必要更改Idle Time-out (minutes)(假设在应用程序池切换到空闲模式时引发Application_end事件。)

工作原理(假设确实如此):

  1. IIS应用程序池设置中有2个设置会影响应用程序挂起或终止的时间。其中一个是Idle Time-out (minutes),默认为20分钟,当自上次请求以来指定的时间过去时,工作进程被暂停或终止。当下一个请求到来时,工作进程将重新启动或再次启动,并引发Application_start事件(因此,如果在global.asax中定义了Application_start处理程序,则执行它)。在我工作的项目中,Application_start大约需要17秒才能完成。因此,如果该站点“独自”持续21分钟然后新请求到来,则需要大约超过17秒才能发回响应(Application_start +页面处理)。当在20分钟的窗口中发送另一个请求时,响应的发送速度明显加快(可能小于1秒),因为Application_start已经处理完毕。
  2. Idle Time-out (minutes)值设置为0会导致工作进程为never be suspended / terminated(至少由于空闲时间 - 可能还有另一个原因如下所述)。

    1. 除了Idle Time-out (minutes)之外,IIS高级设置的Regular time interval (minutes)部分中还有Recycling设置。默认为1740分钟(29小时),是一个常规计划任务,导致应用程序池定期回收(周期已修复)。据我所知,这是为了防止可能的内存泄漏的累积,如果存在泄漏,最终可能会通过耗尽所有内存来使服务器崩溃。应用程序池回收的效果是引发Application_end事件。但是,在应用程序结束后,它不会再次自动启动,因此在实际请求到来之前不会引发Application_start事件(这与第一种情况类似)。因此,在上述Web应用程序的情况下,我将再次花费大约17秒来处理第一个请求,以便在发生回收之后到达。将此值更改为0会关闭回收,但我认为由于可能会随着时间的推移累积内存泄漏(甚至可能由第三方库中的错误引起),因此完全关闭回收是合理的。我了解对于是否设置this value to 0not的意见不一,并且可能会随着时间的推移而发生变化。
    2. 可行的解决方案(不更改IIS设置): 如果请求频繁发送,则应用程序池可能永远不会切换到空闲模式。如果再循环,这也会导致应用程序重新启动。例如,这可以通过使用@Rippo所描述的第三方服务来实现。

      提议的解决方案: 据观察,应用程序池回收导致Application_end事件被引发。假设在将应用程序池切换到空闲模式时也会引发它,在网站的Application_end事件处理程序中创建请求似乎就足够了,在这两种情况下都是如此然后会导致应用程序再次启动(引发Application_start事件)。代码位于答案的顶部。