无法在 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()
}
请求未到达我的网站的原因有很多,感谢 Kevin 和 Twamley 让我看到了可能的问题因为我可以追踪并找到所有这些。
首先,正如凯文所说,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" />
我有一个简单的 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()
}
请求未到达我的网站的原因有很多,感谢 Kevin 和 Twamley 让我看到了可能的问题因为我可以追踪并找到所有这些。
首先,正如凯文所说,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" />