我能够在Ubuntu 18.04上的Azure Kubernetes集群中使用BackgroundService
成功运行.NET 5控制台应用程序。事实上,BackgroundService
是真正运行的全部:只是从队列中抓取消息,执行一些操作,然后在Kubernetes告诉它停止时终止,或者偶尔出现异常。
最后一种情况给我带来了问题。当BackgroundService
遇到不可恢复的异常时,我希望容器停止(完成,或者任何会导致Kubernetes重新启动或销毁/重新创建容器的状态)。
不幸的是,任何时候遇到异常,BackgroundService
* 似乎 * 会命中StopAsync()
函数(从我在日志和控制台输出中看到的),但容器保持在运行状态,永远不会重新启动。我的Main()如下所示:
public static async Task Main(string[] args)
{
// Build service host and execute.
var host = CreateHostBuilder(args)
.UseConsoleLifetime()
.Build();
// Attach application event handlers.
AppDomain.CurrentDomain.ProcessExit += OnProcessExit;
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException);
try
{
Console.WriteLine("Beginning WebSec.Scanner.");
await host.StartAsync();
await host.WaitForShutdownAsync();
Console.WriteLine("WebSec.Scanner has completed.");
}
finally
{
Console.WriteLine("Cleaning up...");
// Ensure host is properly disposed.
if (host is IAsyncDisposable ad)
{
await ad.DisposeAsync();
}
else if (host is IDisposable d)
{
d.Dispose();
}
}
}
字符串
如果相关的话,ProcessExit
和UnhandledException
的事件处理程序存在,以刷新AppInsights遥测通道(可能是阻塞它?):
private static void OnProcessExit(object sender, EventArgs e)
{
// Ensure AppInsights logs are submitted upstream.
Console.WriteLine("Flushing logs to AppInsights");
TelemetryChannel.Flush();
}
private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var thrownException = (Exception)e.ExceptionObject;
Console.WriteLine("Unhandled exception thrown: {0}", thrownException.Message);
// Ensure AppInsights logs are submitted upstream.
Console.WriteLine("Flushing logs to AppInsights");
TelemetryChannel.Flush();
}
型
我只在BackgroundService
中覆盖ExecuteAsync()
:
protected async override Task ExecuteAsync(CancellationToken stoppingToken)
{
this.logger.LogInformation(
"Service started.");
try
{
// Loop until the service is terminated.
while (!stoppingToken.IsCancellationRequested)
{
// Do some work...
}
}
catch (Exception ex)
{
this.logger.LogWarning(
ex,
"Terminating due to exception.");
}
this.logger.LogInformation(
"Service ending.",
}
型
我的Dockerfile很简单,有这一行来运行服务:
ENTRYPOINT ["dotnet", "MyService.dll"]
型
我是不是漏掉了什么明显的东西?我觉得为了让它正常运行,我忘记了把它作为一个Linux容器运行的一些东西。
谢谢你,谢谢
2条答案
按热度按时间xkftehaa1#
下面是如何使用
IHostApplicationLifetime.StopApplication()
的完整示例。字符串
此程序的典型输出如下所示:
型
30byixjq2#
我偶然看到了这篇文章,我不认为RB的回答能解决我的问题,所以我想扩展一下他的回答,以防对其他人有帮助。我在kubernetes中使用.net7和.net8,有两个问题,1)我的后台服务不会退出,2)如果抛出错误,进程会退出,代码0表示kubernetes成功。
在大量的研究和测试之后,你会想要注入
IHostApplicationLifetime
并停止你的应用程序,因为后台服务将运行直到被取消。捕捉异常并设置Environment.ExitCode = 1
以让kubernetes知道有一个失败。字符串