无法在 Web 配置中使用 applicationInitialization 预热页面

Cannot warm up pages using applicationInitialization in webconfig

我有一个简单的 Umbraco 7.7.2 应用程序,我将它托管在 Azure(应用程序服务)上。当我重新启动服务器时,第一次请求页面需要 20-40 秒,这真的很烦人,特别是当负载很高并且您正在 横向扩展 以减少响应时间时。

我已经在我的 webconnfig 中尝试过这个设置,但它似乎不起作用。

<system.webServer>
  <applicationInitialization>
    <add initializationPage="/page1/?warmup=1" hostName="mydomain.com" />
    <add initializationPage="/page1/page2/?warmup=1" hostName="mydomain.com" />
  </applicationInitialization>
</system.webServer>

我可能以错误的方式尝试它,但我所做的是重新启动服务器并且我已经离开它 2-3 分钟而没有请求任何页面。

我检查了我的 Umbraco 日志,应用程序甚至没有启动。 然后我请求了主页,花了 40 秒才出现。

然后我尝试了 mydomain。com/page1 也花了 20 秒,因为这是第一个访问它的请求。

*P.S: 第一次请求后,网站速度非常快,每个页面加载时间不到 100 毫秒

更新

我已经按照 Kevin 的建议实施了重写以停止下一次重定向。 结果,我的 Umbraco 将启动,但请求仍未到达页面。

在我的母版页上,我添加了一行以在日志中写入一行,如果它在查询字符串中有预热并且它可以从浏览器访问页面:

if (!string.IsNullOrWhiteSpace( Request.QueryString["warmup"]))
    {
        var pageC = Model.Content;
        logger.Info(pageC.UrlAbsolute()+" "+ Request.QueryString);
    }

然而,

之后我的日志中没有任何内容

2018-02-08 15:16:51,245 [P7036/D2/T1] INFO Umbraco.Core.CoreBootManager - Umbraco application startup complete (took 12727ms) 2018-02-08 15:16:54,911 [P7036/D2/T1] INFO MyNamespace.Web.CustomStartup - base config done!

这是我根据 Kevin 的回答添加的配置:

 <rule name="No redirect on warmup request (request from localhost with warmup user agent)" stopProcessing="true">
          <match url=".*" />
          <conditions>
            <add input="{REMOTE_ADDR}" pattern="127.0.0.*" />
              </conditions>
          <action type="Rewrite" url="{URL}" />
        </rule>

另外,我在微软找到了另一个类似的配置:

   <rule name="No redirect on warmup request (request from localhost with warmup user agent)" stopProcessing="true">
          <match url=".*" />
          <conditions>
            <add input="{HTTP_HOST}" pattern="localhost" />
            <add input="{HTTP_USER_AGENT}" pattern="Initialization" />
          </conditions>
          <action type="Rewrite" url="{URL}" />
        </rule>

请注意,azure 会预热 http 上的 URL,因此如果您使用重写规则强制 https,则整个站点不会预热,只有重定向模块会预热。然后它需要在 azure 将 Umbraco 添加到负载均衡器并且第一个 https 通过 Umbraco 代码之后完成预热 Umbraco。我们通过在扩展时检查 http 日志发现了这一点。

我们无法弄清楚如何告诉 azure 使用 https 进行预热,因此我们允许 Azure 通过在 {REMOTE_ADDR} 匹配时强制 https 重写为 stopProcessing 之前制定规则来访问 http 上的站点127.0.0.*。

    <rule name="Allow localhost to warmup" stopProcessing="true">
      <match url="(.*)"/>
      <conditions>
        <add input="{REMOTE_ADDR}" pattern="127.0.0.*" />
      </conditions>
    </rule>

我喜欢凯文将停止处理作为第一个重写规则之一的想法。我注意到他没有任何动作,但你给你的动作加了一个。也许试试他的 w/o 动作?它是文件中的第一条规则吗?

我们使用的另一个选项是将此条件添加到任何问题规则中(注意 negate)。

<add input="{REMOTE_ADDR}" pattern="127\.0\.0\.1" negate="true"/>

尝试暂时清除您的重写规则,直到您确信您的预热工作正常,然后一次添加几条规则以查找并修复问题重定向。 Force SSL and Trailing Slash type rules 肯定会导致问题。

此外,主机名很容易给您带来麻烦。它应该与您的生产环境完美匹配。它不使用 DNS 来解析它,它只是与本地站点对话并将其作为 HOST header.

我的热身列表中没有任何查询字符串。也许你应该尝试放弃那些。您实际上并不需要它们,因为您可以将日志记录代码更改为:

if (Request.IsLocal && Request.UserAgent == "IIS Application Initialization Warmup") {
    // log it
}

记录它们是个好主意,因为预热请求不会显示在标准 IIS 日志中。我让我的服务器在热身开始和结束时通过点击使用该 if 语句的特殊第一个和最后一个条目给我发邮件。来自 Azure 的一些有用的细节:

new {
    WEBSITE_HOSTNAME = System.Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME"),
    WEBSITE_INSTANCE_ID = System.Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID"),
    WEBSITE_SITE_NAME = System.Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME"),
    COMPUTERNAME = System.Environment.GetEnvironmentVariable("COMPUTERNAME"),
    USER_AGENT = Request.UserAgent,
    URL = Request.Url,
    WARM_UP_TIME = (DateTime.UtcNow - _start).ToString()
}

请求未到达我的网站的原因有很多,感谢 KevinTwamley 让我看到了可能的问题因为我可以追踪并找到所有这些。

首先,正如凯文所说,HTTPS 是我已解决的问题之一:

 <rule name="No redirect on warmup request (request from localhost with warmup user agent)" stopProcessing="true">
      <match url=".*" />
      <conditions>
        <add input="{HTTP_HOST}" pattern="localhost" />
        <add input="{HTTP_USER_AGENT}" pattern="Initialization" />
      </conditions>
      <action type="Rewrite" url="{URL}" />
    </rule>

然后我可以看到 Umbraco 启动了,但请求没有到达我的页面。

  <rule name="Redirect rquests to www.example.com" stopProcessing="true" enabled="true">
          <match url="(.*)" />
          <conditions >
            <add input="{HTTP_HOST}" pattern="^example\.com$" />
          </conditions>
          <action type="Redirect" url="https://www.example.com/{R:0}" />
        </rule>

我没想到我的请求会到达这个重定向,因为它在我的重写规则的末尾,因此它应该在预热请求没有重定向时停止但是它没有,所以我添加了另一个条件:<add input="{HTTP_USER_AGENT}" pattern="Initialization" negate="true" />

  <rule name="Redirect rquests to www.example.com" stopProcessing="true" enabled="true">
          <match url="(.*)" />
          <conditions logicalGrouping="MatchAll">
            <add input="{HTTP_HOST}" pattern="^example\.com$" />
            <add input="{HTTP_USER_AGENT}" pattern="Initialization" negate="true" />
          </conditions>
          <action type="Redirect" url="https://www.example.com/{R:0}" />
        </rule>

此外,我的设置中有 ipSecurity,因为它是我的测试环境,我不希望它对 public 开放。事实证明,如果我不打开 127.0.0.1,初始化根本无法访问我的站点.....

 <security>
  <ipSecurity allowUnlisted="false">
    <add ipAddress="127.0.0.1" allowed="true" />
    <add ipAddress="x.x.x.x" allowed="true" />