如何让IIS站点在部署后自动启动?

How to get IIS site to start up automatically after deployment?

我有一个 Web API 服务,我正在将其部署到我的各种环境中(使用 Octopus Deploy)。它应该在启动时执行各种任务,例如运行 Entity Framework Code First 所需的任何迁移脚本,以及 Hangfire 管理的一些后台任务。问题是,网站只会在有人第一次调用它时唤醒。我希望它在部署后立即 运行。我可以通过将网络浏览器指向 API 的主页来手动完成,但这需要我记住这样做,如果我要部署到多个触角,那是一个主要的 PITA。

如何强制网站在部署后立即自动启动?

使用 powershell 脚本调用本地主机或部署到 post deploy. The other option would to use the Application Initialization Module 的特定机器。

您需要执行以下步骤 -

  1. 为 Windows 进程激活 (WAS) 和万维网发布 (W3SVC) 服务启用自动启动(默认启用)。

  2. 为应用程序池配置自动启动(默认启用)。

  3. 始终为应用程序池启用运行模式并配置自动启动功能

对于第 3 步,您需要一个实现 IProcessHostPreloadClient 接口的特殊 class。 Windows Process Activation 服务将在其启动期间和每次应用程序池回收后自动调用它。

public class ApplicationPreload : System.Web.Hosting.IProcessHostPreloadClient
{
    public void Preload(string[] parameters)
    {
        //Write code here to kick off the things at startup.
    }
}

Hangfire 上详细记录了完整的过程。 http://docs.hangfire.io/en/latest/deployment-to-production/making-aspnet-app-always-running.html

在控制面板中打开或关闭 windows 功能, 在 "Web Server (IIS) | Web Server | Application Development" 下, select "Application Initialization".

在 IIS 中,在应用程序池的高级设置中, "Start Mode" 应设置为 "AlwaysRunning"。

在 IIS 中,在站点的高级设置中, "Preload Enabled" 应设置为 "true"。

新的部署将导致它再次启动(可能在短暂的延迟之后)。

可以为此使用应用程序初始化模块,正如许多答案所提到的,但是将 PowerShell 步骤放入您的部署中有几个好处...

  1. 它可以为您的网站预热
  2. 它可以像一个非常基本的烟雾测试一样运行
  3. 如果失败,部署在 Octopus 中被标记为失败

我用这个PowerShell script to warm up and check websites after deployment

Write-Output "Starting"

If (![string]::IsNullOrWhiteSpace($TestUrl)) {
    Write-Output "Making request to $TestUrl"

    $stopwatch = [Diagnostics.Stopwatch]::StartNew()
    $response = Invoke-WebRequest -UseBasicParsing $TestUrl -MaximumRedirection 0
    $stopwatch.Stop()

    $statusCode = [int]$response.StatusCode

    If ($statusCode -ge 200 -And $statusCode -lt 400) { 
        Write-Output "$statusCode Warmed Up Site $TestUrl in $($stopwatch.ElapsedMilliseconds)s ms"

        $stopwatch = [Diagnostics.Stopwatch]::StartNew()
        $response = Invoke-WebRequest -UseBasicParsing $TestUrl -MaximumRedirection 0
        $stopwatch.Stop()

        $statusCode = [int]$response.StatusCode
        Write-Output "$statusCode Second request took $($stopwatch.ElapsedMilliseconds)s ms"
    } Else {
        throw "Warm up failed for " + $TestUrl
    }
} Else {
    Write-Output "No TestUrl configured for this machine."
}

Write-Output "Done"