Com*_*eak 5 c# asp.net iis .net-core
我有一个使用 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);
}
}
Run Code Online (Sandbox Code Playgroud)
对于如何更改此行为的任何想法,我都很高兴,因此在不使用此解决方法的情况下,它的行为与以前相同。如果我的应用程序抛出一个未处理的异常,它应该退出并尝试在下一个请求时重新启动。
CaptureStartupErrors当您将应用程序发布到 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>();
} );
}
Run Code Online (Sandbox Code Playgroud)
启动.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();
}
}
Run Code Online (Sandbox Code Playgroud)
以下文件大多是默认的,但如果你想检查:
网络配置:
<?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>
Run Code Online (Sandbox Code Playgroud)
.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>
Run Code Online (Sandbox Code Playgroud)
FolderProfile.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>
Run Code Online (Sandbox Code Playgroud)
正如微软在我的问题中解释的那样,这是预期的行为:
我相信这种行为是预期的,并且是 IIS 进程外和进程内之间的行为差异。然而,我们可以考虑尝试改变进程内的行为。
在 2.2 中,听起来您在进程外使用 IIS,正如您所说,您在完整框架中看到了这种行为。如果 dotnet 进程崩溃,ANCM 将不断尝试重新启动它。
但是,在 3.1/in-process 中,如果应用程序在启动时崩溃,ANCM 将不会重新启动该进程。这是出于以下几个原因:
因为我们是在进程内运行,所以我们需要完全重新启动 w3wp.exe/iisexpress.exe 进程,因为我们不能两次启动 dotnet 运行时而不可能出现不良行为。不断地重新启动 w3wp 进程通常不是一个好主意。我们假设,如果进程在启动时抛出未处理的异常,我们应该要求在重试之前重新部署应用程序。这在当时可能不是正确的决定,但却是行为改变的关键原因。
因此,我的问题的解决方案是使用解决方法或以其他方式处理异常。如果您决定使用解决方法,您应该知道 IIS 具有可配置的快速故障保护功能 ,如果应用程序池重新启动过于频繁,则会停止应用程序池。
AFAIK,您必须调用 Environment.Exit(-1) 的代码可能会工作几次,但我相信调用几次后,IIS 将触发快速故障保护,这将迫使站点不再启动。