【问题标题】:ASP.NET Core 3.1 InProcess hosted app not restarting after exception on startupASP.NET Core 3.1 InProcess 托管应用程序在启动时出现异常后未重新启动
【发布时间】:2020-09-21 22:18:36
【问题描述】:

问题

我有一个使用 IIS 托管 InProcess 的 ASP.NET Core Web 应用程序。我实现了每次启动时抛出的异常。 如预期的那样,IIS 显示此错误页面:

HTTP 错误 500.30 - ANCM 进程中启动失败

此问题的常见解决方案:

  • 该 应用程序启动失败
  • 应用程序启动但 然后停止
  • 应用程序启动但抛出异常 启动时

故障排除步骤:

  • 检查系统事件 记录错误消息
  • 启用记录应用程序 进程的标准输出消息
  • 将调试器附加到 申请流程和检查

欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?LinkID=2028265

在 .Net Core 2.2(使用 CaptureStartupErrors(false))以及经典 ASP.NET 应用程序中,IIS 会尝试在下一个请求时再次启动应用程序。

对于 .Net Core 3.1,它不会尝试重新启动,它只会永远保持这种状态,无论我为 CaptureStartupErrors 设置什么。

解决方法

我可以通过捕获异常并退出来解决此问题 - 如果我这样做,它将按预期运行:

public static void Main(string[] args)
{
    try
    {
        CreateWebHostBuilder(args).Build().Run();
    }
    catch (Exception)
    {
        Environment.Exit(-1);
    }
}

预期行为

对于如何更改此行为的任何想法,我都会很高兴,因此在不使用此解决方法的情况下,它的行为与以前相同。如果我的应用程序抛出未处理的异常,它应该退出并尝试在下一个请求时重新启动。

我尝试过的

  • CaptureStartupErrors 使用不同的值
  • 寻找改变这种行为的配置参数
  • 在“发布”-配置而不是“调试”中发布
  • 创建了issue on Github

重现问题的代码

Repository on Github

当您将应用程序发布到 IIS 时会出现此问题,并且在没有 IIS 的情况下无法重现。

程序.cs:

public class Program
{
    public static void Main(string[] args)
    {
        File.AppendAllText("log.txt", $"{DateTime.Now.ToLongTimeString()}:Starting\r\n");
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateWebHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder( args )
            .ConfigureWebHostDefaults( webBuilder =>
            {
                webBuilder
                    .UseStartup<Startup>();
            } );
}

Startup.cs:

public class Startup
{
    public Startup( IConfiguration configuration )
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices( IServiceCollection services )
    {

    }

    public void Configure( IApplicationBuilder app, IHostingEnvironment env )
    {
        throw new Exception();

    }
}

以下文件大多是默认的,但如果你想检查

web.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath="dotnet" arguments=".\WebApplication20.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="InProcess" />
    </system.webServer>
  </location>
</configuration>

.csproj:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
  </ItemGroup>

</Project>

文件夹配置文件.pubxml:

<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121. 
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <DeleteExistingFiles>False</DeleteExistingFiles>
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
    <LastUsedBuildConfiguration>Debug</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <PublishProvider>FileSystem</PublishProvider>
    <PublishUrl>C:\inetpub\wwwroot\test</PublishUrl>
    <WebPublishMethod>FileSystem</WebPublishMethod>
    <SiteUrlToLaunchAfterPublish />
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <ProjectGuid>9ec27b57-5f45-4286-aa7c-12abad61a153</ProjectGuid>
    <SelfContained>false</SelfContained>
  </PropertyGroup>
</Project>

【问题讨论】:

  • 什么错误导致应用程序崩溃,这个错误可以解决吗?
  • 这更像是一个一般性问题,但我来自SocketFailure (ReadSocketError/ConnectionReset,在连接到我们的 Redis 服务器时系统重新启动后随机发生,因为系统的某些部分似乎没有完全初始化此时。实施重试是一种选择,但我们更愿意使用 IIS 的本机功能来包装完整的应用程序并处理所有未来的事件,而不是针对这个问题的单一案例实施特定的解决方案。
  • @Compufreak 我对这个问题有类似的感觉,我什至在 github 上写了评论github.com/dotnet/aspnetcore/issues/…

标签: c# asp.net iis .net-core


【解决方案1】:

尝试验证目标框架的版本是 3.+ 还是 3,然后再检查 sdk runtime for 3.+

属性需要验证:- netcoreapp3.1 --> 处理中

完成所有这些后一切正常,我刚刚重新启动系统并打开解决方案来运行它。

如果还是不行,试试看告诉我

【讨论】:

  • 我检查了所有这些,没关系。仅在将解决方案发布到 IIS 后才会出现此问题。我用包含您要求的数据的文件编辑了我的帖子。我还将代码上传到 Github:github.com/Compufreak345/ExampleNetCore31App - 如果您将此应用程序发布到安装了 asp.net 核心托管模块的 IIS,您应该能够重现该问题。
【解决方案2】:

作为 Microsoft did explain in my issue,这是预期行为:

我相信这种行为是意料之中的,是一种行为差异 IIS 进程外和进程内。但是,我们可以考虑 试图改变进程中的行为。

正如你所说,在 2.2 中,听起来你在进程外使用 IIS 您在完整框架中看到了这种行为。 ANCM 将不断尝试 如果 dotnet 进程崩溃,请重新启动它。

但是,在 3.1/in-process 中,如果应用程序在启动时崩溃, 如果在启动时崩溃,ANCM 将不会重新启动该进程。这是 有几个原因:

因为我们是在进程内运行,所以需要重启 w3wp.exe/iisexpress.exe 进程完全因为我们无法启动 dotnet 运行两次,没有不良行为的可能性。不断地 重新启动 w3wp 进程通常不是一个好主意。我们做了一个 假设如果一个进程在启动时抛出一个未处理的异常, 在重试之前,我们应该要求重新部署该应用程序。这 当时可能不是正确的决定,但这是一个关键 行为改变的原因。

因此,我的问题的解决方案是使用解决方法或以其他方式处理异常。如果您决定使用该解决方法,您应该知道 IIS 有一个 configurable rapid failure protection 如果应用程序池重新启动太频繁,它会停止它。

AFAIK,您必须调用 Environment.Exit(-1) 的代码可能会尝试几次,但我相信在调用几次之后,IIS 将触发快速故障保护,这将迫使站点无法启动再次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-10
    • 2014-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多