【问题标题】:IIS ApplicationPool fails to start properly without errorIIS 应用程序池无法正常启动且没有错误
【发布时间】:2021-08-31 06:55:52
【问题描述】:

我们的 IIS 部署面临一个奇怪的问题。

ApplicationPools 有时无法正确启动,但这样做时不会抛出错误。 应用程序池中唯一包含的站点没有响应(甚至不返回 500 等,只是在一段时间后超时)。

就 IIS 而言,ApplicationPool 和站点已启动并正在运行(未停止)。

重新启动站点或 ApplicationPool 并不能解决问题。

但是,删除站点和 ApplicationPool 并使用相同的属性重新创建它确实可以解决问题。

一旦任何 ApplicationPool 达到此状态,解决此问题的唯一方法(据我们所知)就是重新创建整个 ApplicationPool。

我们很乐意以自动化方式执行此操作,但不会分别捕获和处理错误。

一些背景数据:

  • 我们使用的是 IIS 版本 10
  • ApplicationPool 似乎可以正确启动。 EventLog 指出Application '<OUR_APP>' started successfully.

我们怀疑问题可能是多个 ApplicationPool 启动同时发生(因为它们是由我们的 CI/CD 管道自动触发的)。

现在,我绝不是 IIS 专家,所以我的问题是:

  • 是否有可能,许多应用程序池启动(大约 20-60 次)几乎同时发生会导致这种行为?
  • 我可以做些什么来进一步调查?

【问题讨论】:

    标签: iis iis-10 application-pool


    【解决方案1】:

    是否有可能启动许多应用程序池(大约 20-60) 大致同时发生会导致这种行为吗?

    很难说。应用程序池只是一个空容器,主要是花费时间并对这个数量施加限制的是您的应用程序代码和依赖项在启动和运行时所做的事情,而 dotnet 预编译开销很小。

    我可以做些什么来进一步调查?

    1. 检查 Windows 文件夹中的 HTTPERR 日志 - 如果您没有看到在其他地方记录的请求,可能会提供线索。

    2. 监控 w3wp.exe 进程本身 - 这些是您的应用程序池(也称为“应用程序域”)。他们可能会卡住而不是“正确”崩溃,这听起来像你的情况。

    假设您所有的应用程序都正常工作,而您只是想要一种恢复随机故障的方法,试试这个...

    当您的应用程序池损坏时,从 PowerShell 或 ISE(以管理员身份)在您的服务器上运行以下命令以查看正在运行的 IIS 工作进程:

    Get-WmiObject Win32_Process -Filter "name = 'w3wp.exe'" | Select-Object ProcessId,CommandLine
    

    以上输出工作进程 ID 和用于启动它们的参数。在参数中,您可以看到站点名称 - 使用正确的 ProcessId 和命令 Stop-Process -Force -Id X(将 X 替换为 ProcessId 编号)强制终止进程。杀死进程后尝试访问应用是否成功启动?

    如果您知道要杀死的应用程序池的名称,您可以使用此代码终止进程:

    $AppPoolName = 'NAMEOFMYAPPPOOL';
    Stop-Process -Force -id (Get-WmiObject Win32_Process -Filter "name = 'w3wp.exe' AND CommandLine like '%-in%$($AppPoolName)%'").ProcessId
    

    (将NAMEOFMYAPPPOOL替换为应用程序池的名称,并以管理员身份运行)

    如果杀死停滞的进程足以让它成功重新启动,那么编写一个简单的健康检查脚本将相当容易。我会阅读每个站点的绑定,对每个绑定发出 HTTP 请求,并确认应用程序池确实正在运行/响应并返回 200 OK 响应。如果请求在合理的超时后失败,请尝试终止进程并重新请求 HTTP 请求以重新启动应用程序池。添加一些重试逻辑,并可能在尝试之间添加延迟,以免卡在循环中。

    只是一个想法 - 尝试为每个应用程序池提供自己的临时文件夹 - 在每个站点的 web.config 中配置:

    <system.web>
      <compilation tempDirectory="D:\tempfiles\apppoolname" />
    

    在启动过程中的交叉对话可能是奇怪的根源。

    【讨论】:

    • 感谢您的回答。一旦问题再次出现,我会尝试这个!
    【解决方案2】:

    问题似乎是由于我们的部署脚本没有等待应用程序池实际处于Stopped 状态,然后继续删除旧的应用程序文件并用新文件替换它们并立即再次启动应用程序池。

    我们在今年早些时候注意到了与此相关的问题,即由于仍在使用文件而无法删除文件,即使在停止 ApplicationPool 之后(我们通过实施重试机制“解决了”)...

    解决方案

    停止ApplicatonPool后调用以下代码似乎可以解决问题......

    $stopWaitCount = 0;
    while ((Get-WebAppPoolState -Name $appPool).Value -ne "Stopped" -and $stopWaitCount -lt 12)
    {
        $stopWaitCount++
        Write-Log "Waiting for Application-Pool '$appPool' to stop..."
        Start-Sleep -Seconds $stopWaitCount
    }
    

    我们在 2 天前实施了此操作,此后 100 多次部署中均未出现此问题。

    【讨论】:

      猜你喜欢
      • 2020-10-15
      • 2012-01-20
      • 1970-01-01
      • 2018-09-15
      • 1970-01-01
      • 1970-01-01
      • 2020-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多