【问题标题】:Fixing slow initial load for IIS修复 IIS 的缓慢初始加载
【发布时间】:2012-11-03 09:36:50
【问题描述】:

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

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

A. Use the Application Initialization plugin

B. Use Auto-Start with .NET 4

C. Disable the idle-timeout (under IIS Reset)

D. Precompile the site

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

编辑

执行 C 似乎足以让我的网站热身,但我发现我的网站缓慢的真正根源与实体框架有关,我似乎无法做到弄清楚为什么会变冷。请参阅this 问题,很遗憾尚未回答已回答!

我最终只需要创建一个warm up script 来偶尔访问我的网站以确保它保持速度。

【问题讨论】:

  • 嗨朋友,表演C够吗?为什么 ?我们只需要使用它还是也需要禁用回收?总觉得IIS7.5的第二天第一次请求很慢

标签: asp.net .net-4.0 iis-7.5


【解决方案1】:

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

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

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

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

来自技术网:

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

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

【讨论】:

  • 那么你会建议只禁用空闲超时吗?这会导致问题(我猜这是有原因的)吗?
  • 这实际上并不能解决我的问题(请参阅我的编辑),但我接受了,因为您确实回答了我的原始问题。
【解决方案2】:

虚拟主机挑战

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

ASP.NET MVC 开销

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

另一种测试性能的方法

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

另一个有用脚本的测试

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

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

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

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

ALSO:确保将字符串 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";
    }
}

【讨论】:

    【解决方案3】:

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

    在共享主机空间中,预热脚本是最好的第一级防御(自助是最好的帮助)。这是一篇分享idea on how to do it from your own web application的文章。

    【讨论】:

    • 刚刚更新了这个旧线程,以防有人搜索相同
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

      https://flow.microsoft.com

      【讨论】:

        【解决方案6】:

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

        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

        【讨论】:

          【解决方案7】:

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

          【讨论】:

            猜你喜欢
            • 2014-02-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-07-18
            • 2016-04-25
            • 2017-03-01
            • 2012-05-23
            • 1970-01-01
            相关资源
            最近更新 更多