【问题标题】:Docker Graceful Shutdown from Dotnet Core 2.0 appDotnet Core 2.0 应用程序的 Docker 正常关闭
【发布时间】:2019-01-11 17:08:42
【问题描述】:

我有一个在本地 Docker Linux 容器(Docker CE 18.03.1 稳定通道)中运行的 .NET Core 2.0 控制台应用程序,并且正在尝试处理正常关闭。

我的应用有AppDomain.CurrentDomain.ProcessExitAssemblyLoadContext.Default.Unloading 的处理程序:

        AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
        AssemblyLoadContext.Default.Unloading += Default_Unloading;

处理程序只是在调用时写入日志消息。

我发现,当我执行docker stop <containerid> 时,没有 处理程序被调用,并且经过短暂的延迟。容器只是停止运行。我尝试在 Visual Studio 中调试应用程序,并尝试在没有调试器的情况下运行。在所有情况下,处理程序都不会被调用。

我还缺少其他一些魔法咒语吗?

【问题讨论】:

    标签: docker .net-core


    【解决方案1】:

    我无法重现这种行为。

    这是我在控制台应用程序中使用的代码:

        private static readonly AutoResetEvent _closing = new AutoResetEvent(false);
    
        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
            AssemblyLoadContext.Default.Unloading += Default_Unloading;
    
            Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    Console.WriteLine(DateTime.Now.ToString());
                    Thread.Sleep(1000);
                }
            });
            Console.CancelKeyPress += new ConsoleCancelEventHandler(OnExit);
            _closing.WaitOne();
        }
    
        private static void Default_Unloading(AssemblyLoadContext obj)
        {
            Console.WriteLine("unload");
        }
    
        private static void CurrentDomain_ProcessExit(object sender, EventArgs e)
        {
            Console.WriteLine("process exit");
        }
    
        protected static void OnExit(object sender, ConsoleCancelEventArgs args)
        {
            Console.WriteLine("Exit");
            _closing.Set();
        }
    

    使用这个 docker 文件:

    FROM microsoft/dotnet:2.0-sdk
    WORKDIR /app
    
    # copy csproj and restore as distinct layers
    COPY *.csproj ./
    RUN dotnet restore
    
    # copy and build everything else
    COPY . ./
    RUN dotnet publish -c Release -o out
    ENTRYPOINT ["dotnet", "out/shutdown.dll"]
    

    这是输出:(带有docker stop <id>

    06/01/2018 16:31:16
    06/01/2018 16:31:17
    06/01/2018 16:31:18
    unload
    process exit
    

    我正在使用带有 Linux 容器的 Docker for Windows。

    【讨论】:

    • 感谢您的回答。我能够从您的示例代码中获得预期的结果,但不能从我自己的(几乎相同的)代码中获得;我仍在试图弄清楚有什么不同。主要区别在于我使用了 VS2017“添加 Docker 支持”选项,该选项生成了一个 Dockerfile 并在我的解决方案中添加了一个 docker-compose“项目”。在功能上,它们似乎与您的样本大致相同,但在操作上,它们却大不相同。当我深入了解它时会更新。
    • 我现在尝试使用 vs 2017 和“添加 Docker 支持”,这也适用于我。我在从 vs 调试它时遇到了问题,但这是一个不同的故事。您是否正在使用应用程序的发布版本从控制台尝试它?因为如果你在调试中构建它,它什么也不做。
    【解决方案2】:

    非常奇怪的行为。
    我遇到了同样的问题,对我来说,当我在 dockerfile 中使用以下入口点时,它确实不起作用

    ENTRYPOINT dotnet DockerTest.dll
    

    当我将其更改为以下内容时,它工作

    ENTRYPOINT ["dotnet", "DockerTest.dll"]
    

    我希望这会有所帮助:)

    【讨论】:

    • 这行不通。无法保证使用该 ENTRYPOINT 会强制容器始终打开。
    猜你喜欢
    • 2017-07-29
    • 2012-02-04
    • 2018-02-11
    • 2019-08-07
    • 1970-01-01
    • 2018-01-16
    • 1970-01-01
    • 1970-01-01
    • 2017-02-12
    相关资源
    最近更新 更多