141

IIS 对低流量网站有一个烦人的功能,它会回收未使用的工作进程,导致第一个用户在一段时间后访问该站点会出现极长的延迟(30 多秒)。

我一直在寻找解决问题的方法,并且找到了这些潜在的解决方案。

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

B.使用 .NET 4 的自动启动

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

D.预编译网站

我想知道其中哪一个是首选,更重要的是,为什么同一问题有这么多解决方案?(我的猜测是他们不是,我只是没有正确理解某些东西)。

编辑

执行C似乎足以让我的网站热身,但我发现我的网站缓慢的真正根源与实体框架有关,我似乎无法弄清楚它为什么会变冷。看到这个问题,不幸的是还没有回答,还没有回答!

我最终只需要制作一个热身脚本来偶尔访问我的网站以确保它保持快速。

4

7 回答 7

40

选项 A、B 和 D 似乎属于同一类别,因为它们只影响初始启动时间,它们会预热网站,例如编译和加载内存中的库。

使用 C 设置空闲超时应该足够了,以便快速处理对服务器的后续请求(重新启动应用程序池需要相当长的时间 - 以秒为单位)。

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

除了在用户不活动的情况下关闭应用程序池这一事实外,应用程序池还将默认每 1740 分钟(29 小时)回收一次。

来自技术网:

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

只要保留应用程序池回收,就足够了。但是,如果您真的想要大多数组件的顶级性能,您还应该使用您提到的应用程序初始化模块之类的东西。

于 2012-11-14T20:12:08.080 回答
10

虚拟主机挑战

您必须记住,如果您像我们许多人(较小的公司和个人)一样托管在共享服务器上,则没有任何机器配置选项可用。

ASP.NET MVC 开销

如果我的网站在 20 分钟内没有被点击(并且 Web 应用程序已停止),它至少需要 30 秒。这很糟糕。

另一种测试性能的方法

还有另一种方法可以测试它是您的 ASP.NET MVC 启动还是其他。在您的网站上放置一个普通的 HTML 页面,您可以直接点击它。
如果问题与 ASP.NET MVC 启动有关,那么即使 Web 应用程序尚未启动,HTML 页面也会几乎立即呈现。
这就是我第一次认识到问题出在 ASP.NET MVC 启动中的方式。我在任何时候都加载了一个 HTML 页面,它的加载速度非常快。然后,在点击该 HTML 页面后,我点击了我的 ASP.NET MVC URL 之一,我会收到 Chrome 消息“等待 raddev.us...”

另一个有用脚本的测试

之后,我编写了一个 LINQPad(查看http://linqpad.net了解更多信息)脚本,该脚本每 8 分钟访问一次我的网站(少于应用程序卸载的时间——应该是 20 分钟),然后我让它运行了几个小时。

当脚本运行时,我访问了我的网站,每次我的网站都以惊人的速度出现。这给了我一个好主意,我遇到的缓慢很可能是因为 ASP.NET MVC 启动时间。

获取 LinqPad,您可以运行以下脚本——只需将 URL 更改为您自己的并让它运行,您就可以轻松地进行测试。祝你好运。

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

:确保将 String URL 变量更改为指向将从 ASP.NET MVC 站点加载路由的 URL,以便引擎运行。

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";
    }
}
于 2016-08-11T01:26:49.267 回答
3

编写一个 ping 服务/脚本来访问您的闲置网站是最好的方法,因为您将拥有完全的控制权。如果您租用了专用主机箱,则可以使用您提到的其他选项。

在共享主机空间中,预热脚本是最好的第一级防御(自助是最好的帮助)。这是一篇文章,它分享了如何从您自己的 Web 应用程序中执行此操作的想法。

于 2016-05-21T22:09:10.287 回答
2

我会使用B因为它与工作进程回收一起意味着在回收时只会有延迟。这避免了通常与响应空闲后的第一个请求的初始化相关的延迟。您还可以保留回收的好处。

于 2012-11-14T20:31:57.887 回答
2

按计划 ping 站点的一个不错的选择是使用 Microsoft Flow,每月最多可免费运行 750 次“运行”。创建一个每小时访问您的站点以保持其温暖的流非常容易。您甚至可以通过创建单个流来解决其 750 的限制,该流具有将您的站点的多个点击分开的延迟。

https://flow.microsoft.com

于 2016-11-27T20:40:21.033 回答
2

有关如何帮助解决性能问题的提示,请参阅本文。这包括与“冷启动”部分下的启动相关的性能问题。无论您在本地还是在生产中使用哪种类型的服务器,大部分内容都将很重要。

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

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

如果任何 IIS 服务器没有对 Internet 的传出访问权限,请通过在 machine.config 中添加 generatePublisherEvidence=”false” 来关闭证书吊销列表 (CRL) 检查 Authenticode 二进制文件。否则,每个工作进程在启动期间可能会挂起超过 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。但是,如果不小心使用,这不会带来太多的性能提升。这是因为每个进程加载的所有二进制文件的基本加载地址必须在构建时仔细设置,以免重叠。如果由于地址冲突而在加载二进制文件时必须重新设置它们的基础,则几乎所有使用 NGEN 的性能增益都将丢失。 http://msdn.microsoft.com/en-us/magazine/cc163610.aspx

于 2015-10-28T21:20:01.610 回答
0

在 4 分钟不活动后,我在第一个请求上得到了一致的 15 秒延迟。我的问题是我的应用程序正在对 SQL Server 使用 Windows 集成身份验证,并且服务配置文件与服务器位于不同的域中。这导致在应用程序初始化时从 IIS 到 SQL 的跨域身份验证 - 这是我延迟的真正原因。我改为使用 SQL 登录而不是 Windows 身份验证。延迟立即消失了。我仍然拥有所有应用程序初始化设置以帮助提高性能,但在我的情况下可能根本不需要它们。

于 2019-08-22T20:10:15.800 回答