Azure Web角色启动时,Application_Start循环

时间:2016-12-07 12:09:02

标签: asp.net-mvc azure iis azure-cloud-services

我们有一个在Azure云服务Web角色中运行的ASP.NET MVC应用程序。 MvcApplication.Application_Start()中有很多启动代码,在其他事情中进行数据库初始化,这可能需要几分钟或更长时间才能运行。

有时,当角色实例启动时(部署或重启后),应用程序无法首次启动。我们可以从日志中看到Application_Start触发,获取某种方式,然后从头开始。在重复此过程几次之后,应用程序通常会完成其启动例程并开始处理请求,但偶尔会进入一个看似永无止境的循环,唯一的解决方案是重新启动或重新映像角色实例。

我们看到记录的任何错误,Application_End根本没有触发。每次Application_Start触发时,Serilog的HttpRequestIdEnricher都会记录不同的请求ID,表示每次都有新的HttpContext.Current。我在本地运行时从未见过这种行为,仅在Azure中。

任何想法发生了什么?

更新

只有在网站上发出多个请求时,才会出现此行为。当重新启动生产中的角色实例时,最常见(并且令人愤怒); UAT环境通常启动正常,但我可以通过在不同的浏览器选项卡中发出多个请求来激发此问题。我还尝试实施类似this的内容 - 让WebRole.OnStart ping网页网址以确保网站在退出之前运行 - 但这只能确保网站永远不会出现。< / p>

所以我的猜测是IIS应该受到指责:当Application_Start正在进行时出现新请求时,它似乎正在重新启动应用程序,而不是让原始请求完成。

1 个答案:

答案 0 :(得分:2)

我似乎已将此跟踪到IIS应用程序池配置中的一个或两个设置。

IIS app pool ping settings

我最初假设Startup Time Limit是最可能的罪魁祸首,并尝试将其设置为240秒(因为我们的应用程序通常需要2-3分钟才能启动),但问题仍然存在。我随后也将Ping Maximum Response Time改为240秒,这似乎已经治好了。

当启动陷入循环时,通常(并非总是)连续启动之间的间隔为2分钟,因此我假设IIS等待30秒(默认为Ping Period),然后发出请求并且在重新启动工作进程之前等待90秒的响应。

此Powershell代码在Web角色启动时运行的脚本中配置相关设置:

Import-Module WebAdministration

Get-ChildItem IIS:\AppPools | ForEach-Object {
    $appPool = "IIS:\AppPools\" + $_.Name
    $startupLimit = New-TimeSpan -Minutes 4
    Set-ItemProperty $appPool -Name processModel.startupTimeLimit -Value $startupLimit
    Set-ItemProperty $appPool -Name processModel.pingResponseTime -Value $startupLimit
}

应该可以对Microsoft.Web.Administration.ServerManager做同样的事情,但我还没有尝试过。