iis 如何处理Asp:.Net Core API在构建主机期间崩溃的情况

g6ll5ycj  于 2023-03-08  发布在  .NET
关注(0)|答案(1)|浏览(220)

我有一个Asp.NET核心API,目前是.Net6。
基本上Program.cs是如下所示的形式。

public class Program
{
    public static void Main(string[] args)
    {
        var host = BuildWebHost(args).Build();
        host.Run();
    }

    public static IHostBuilder BuildWebHost(string[] args) =>
        Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseKestrel(options =>
            {
                options.Limits.MinRequestBodyDataRate = new MinDataRate(100, TimeSpan.FromSeconds(30));
            })
            .UseIISIntegration()
            .UseStartup<Startup>();
        });
}

在Startup类中,我们有一些 Boot 代码,它们需要访问数据库,以获得启动期间所需的各种设置。
API使用AspNetCoreModuleV 2处理程序托管在IIS内部。
如果数据库不可用,那么如果我只是将API作为可执行文件运行,可执行文件就会停止。
但是在IIS内部,API启动,然后崩溃,然后IIS报告500。这是正确的。
但是使用API的进程并没有被杀死,而是由于某种原因而保持活动状态。
因此,现在我有一个“死”的、配置错误的API可执行文件,它无法启动并连接到IIS应用程序池。
因此,如果我刷新网站,那么IIS只是立即报告500再次。
这意味着,如果我的数据库在API启动的时间范围内处于离线状态,那么我们必须手动重新启动API,然后它才能再次开始响应。
有没有什么好的解决方案来避免这种情况,无论是在web.config中还是通过从.Net代码内部发出“我死了”的信号-尝试重新启动我。
AspNetCore标记中的选项似乎没有起到作用--或者我调错了。(https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/web-config?view=aspnetcore-7.0 #aspnetcore元素的属性)
在最好的情况下,IIS会在2-5分钟内报告500,然后再次尝试启动可执行文件,然后继续这样直到数据库再次启动。
此致/Anders
(编辑)仍然对IIS可以处理此问题的某些方面感兴趣,因此我们不必围绕它构建额外的基础设施。
但是受到下面Jerrys脚本的启发,我做了一个修改版本,可以查找所有以我的可执行文件名运行的进程,我可以从进程Username中找到站点,删除“iisappool”,然后ping每个站点。(大多数发布在这里是为了自己参考)
这不会重新启动任何东西,只是循环通过我们的网站作为一个手动过程,现在,所以我们不必检查他们一个接一个。
将很容易扩展到连接应用程序池和进程用户名,因此它也可以重新启动,如果它报告的任何东西,但200。

$apiProcesses = Get-Process NAME_OF_YOUR_EXECUTABLE -IncludeUserName

foreach($process in $apiProcesses)
{
    $siteDomain = $process.userName -replace "IIS APPPOOL\\", ""
    Write-Host ("Checking $siteDomain")
     
    $testUri = "https://$siteDomain/api/license"

    $Request = [system.Net.WebRequest]::Create($testUri)

    try {
        # Get the response
        $Response = $Request.GetResponse()
    } catch [System.Net.WebException] {
        # If it fails, get Response from the Exception
        $Response = $_.Exception.InnerException.Response
    }

    if(200 -ne ($Response.StatusCode -as [int])){
        Write-Host "          Site $testUri seems down" 
    }
}
u0sqgete

u0sqgete1#

数据库脱机不会导致应用程序池崩溃。IIS没有检测错误500的内置方法。您可以创建PowerShell脚本以每5分钟检查一次响应代码,如果是500,则重新启动应用程序池。

# Loop indefinitely
while ($true) {
    Write-Host "checking status"

    $App = (Get-Website 'Default Web Site')

    # Uri for the application
    $TestUri = 'http://localhost/api/weatherforecast' -f $App.path

    # Create WebRequest
    $Request = [system.Net.WebRequest]::Create($TestUri)
    try {
        # Get the response
        $Response = $Request.GetResponse()
    } catch [System.Net.WebException] {
        # If it fails, get Response from the Exception
        $Response = $_.Exception.InnerException.Response
    }

    # The numerical value of the StatusCode value is the HTTP status code, ie. 503
    if(500 -eq ($Response.StatusCode -as [int])){
        # Restart the app pool
        Restart-WebAppPool -Name $App.applicationPool
        }

    # Sleep for 5 minutes (300 seconds)
    Start-Sleep -s 300
}

将Website名称和TestUri更改为您的名称。这假设您将Web应用程序直接部署到website。如果您只是将应用程序添加到website下,则可以替换为

foreach($App in @(Get-WebApplication -Site 'Default Web Site')){

    # Uri for the application
    $TestUri = ''http://localhost/api/weatherforecast' -f $App.path

编辑和运行powershell脚本使用PowerShell伊势的方式。

相关问题