我正在尝试获取有关 asp net core 如何处理停止 IHostedService 的信息。
在我的机器上,如果我有一个使用 IHostedService 执行的应用程序,并且如果我向它发送 SIGTERM,我会观察到 StopAsync() 方法按预期调用,并且取消标记发生更改等,因此我的代码可以正常处理 SIGTERM。但是,如果我尝试在另一个环境中,似乎在 SIGTERM 上 IHostedService 被残酷地停止,而没有调用 StopAsync() 代码。所以我有一种感觉这取决于版本和潜在的环境(macos vs linux)
是否有关于 Asp .net core 将考虑“优雅”关闭需求的行为记录,具体取决于 asp .net core 版本等?我什么也没找到。理想情况下,应该记录发送 SIGTERM 时 IHostedService 的行为
简洁版本
\n使用RunConsoleAsync()而不是Run或RunAsync。
另一种选择是在调用其他方法之一之前调用UseConsoleLifetime() 。RunConsoleAsync()在内部执行此操作
Environment.Exit()从 .NET 6 开始,从应用程序本身调用时不会使用正常关闭。
解释
\nStopAsync当主机关闭时将被调用。通常,除非主机以控制台生命周期运行,否则不会监视 SIGTERM 或 SIGKILL。这是 .NET Core 3 中添加的通用主机的一项功能,并取代了旧的 WebHost。更新了 ASP.NET Core 文档,并在通用 .NET 部分中添加了新文档
不幸的是,这意味着主机和中间件的行为是重复的,甚至分布在不同的部分。
\n主机关闭部分描述了关闭行为,特别是关于 SIGTERM、MacOS、Linux 等。如果ConsoleLifetime使用,则监视 SIGTERM、SIGKILL 等。该部分并未说明如何执行此操作。
这记录在.NET Generic Host for ASP.NET Core页面的RunConsoleAsync部分中:
\n\n\nRunConsoleAsync 启用控制台支持、构建并启动主机,并等待 Ctrl+C/SIGINT (Windows)、\xe2\x8c\x98+C (macOS) 或 SIGTERM 关闭。
\n
当使用控制台生命周期时,SIGINT、SIGTERM、SIGKILL 将导致正常关闭:
\n\n\n如果使用 ConsoleLifetime,它会侦听以下信号并尝试正常停止主机。
\n\n
\n- SIGINT(或 CTRL+C)。
\n- SIGQUIT(或 Windows 上的 CTRL+BREAK,Unix 上的 CTRL+\\)。
\n- SIGTERM(由其他应用程序发送,例如 docker stop)。
\n
Environment.Exit虽然不是正常关闭。这在 .NET 6 之前引起了问题:
\n\n在 .NET 6 之前,.NET 代码无法优雅地处理 SIGTERM。为了解决此限制,ConsoleLifetime 将订阅 System.AppDomain.ProcessExit。当 ProcessExit 被引发时,ConsoleLifetime 将通知主机停止并阻塞 ProcessExit 线程,等待主机停止。
\n
\n\n这导致了其他问题,因为 SIGTERM 不是引发 ProcessExit 的唯一方式。它也由应用程序中调用Environment.Exit 的代码引发。Environment.Exit 不是关闭 Microsoft.Extensions.Hosting 应用模型中进程的一种优雅方式。
\n
这在 .NET 6 中发生了变化:
\n\n\n在 .NET 6 中,支持并处理 POSIX 信号。这允许 ConsoleLifetime 优雅地处理 SIGTERM,并且在调用 Environment.Exit 时不再参与其中。
\n
和
\n\n\n对于.NET 6+,ConsoleLifetime 不再具有处理Environment.Exit 场景的逻辑。调用Environment.Exit并需要执行清理逻辑的应用程序可以自行订阅ProcessExit。在这种情况下,托管将不再尝试正常停止主机。
\n
| 归档时间: |
|
| 查看次数: |
1720 次 |
| 最近记录: |