繁体   English   中英

在 docker 容器中正常关闭 .NET Core 3.1 应用程序

[英]Graceful Shutdown of .NET Core 3.1 application within a docker container

我一直在尝试不同的方法来通过对 SIGTERM 信号做出反应来优雅地关闭我的应用程序,但是我似乎无法让它工作。

我已经实施了以下服务:

public class ShutdownService : IHostedService
{
    private readonly IHostApplicationLifetime _appLifetime;
    private readonly ILogger<ShutdownService> _logger;

    public ShutdownService(IHostApplicationLifetime appLifetime, ILogger<ShutdownService> logger)
    {
        _appLifetime = appLifetime;
        _logger = logger;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Initializing shutdown service.");
        Console.CancelKeyPress += (sender, eventArgs) =>
        {
            _logger.LogInformation("Ctrl-C detected. Initiating shutdown...");
            _appLifetime.StopApplication();
            eventArgs.Cancel = true;
        };
        _logger.LogInformation("Now listening to Ctrl-C.");
        cancellationToken.Register(() =>
        {
            _logger.LogInformation("SIGTERM detected. Initiating shutdown...");
            _appLifetime.StopApplication();
        });
        AppDomain.CurrentDomain.ProcessExit += (sender, e) =>
        {
           _logger.LogInformation("SIGTERM detected. Initiating shutdown...");
           _appLifetime.StopApplication();
        };

        _logger.LogInformation("Now listening to SIGTERM.");
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Executing graceful shutdown.");
        return Task.CompletedTask;
    }
}

我已经在我的服务中注册了它:

Host.CreateDefaultBuilder(args)
    .UseDefaultServiceProvider(o => o.ValidateScopes = false)
    .UseSystemd()
    .ConfigureServices((hostContext, services) =>
    {
        services.AddHostedService<ShutdownService>();
    }

在我的 dockerfile 中,我使用 shell 脚本作为入口点,因为我必须在容器启动时启动多个应用程序。 该脚本如下所示:

#!/bin/bash
dotnet /App/myGracefulShutdownApp.dll &
pid=$!
dotnet /App2/myOtherApp.dll &
trap 'kill -SIGTERM $pid' SIGTERM SIGINT
wait $pid

我已经验证,当容器启动时,ShutdownService 正在运行。 我已经验证,当我停止容器时,正确的进程 ID 会被 trap 命令杀死。

如果重要的话,容器以非 root 用户身份运行。 我也尝试过在容器内使用 kill 命令(以查看用户是否有权执行 kill 命令并且确实如此),但应用程序仍然不执行 StopAsync。

如果需要,我很乐意提供更多信息。 已经感谢您的帮助!

由于我仍然无法弄清楚为什么我的应用程序没有收到 SIGTERM 命令,我选择使用“Shutdown”方法扩展我的 web API,当启动脚本捕获 SIGTERM 信号时,该方法将使用 cURL 命令调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM