如何使用 dotnet 核心应用程序终止 docker 容器
How to terminate docker container with dotnet core application
我有一个 dotnet Core 3.1 应用程序,在 Program.cs
中创建了以下主机
public static async Task Main(string[] args)
{
var configuration = ConfigurationFactory.CreateConfiguration();
var appName = configuration.GetAppName();
Log.Logger = configuration.CreateSerilogLogger();
try
{
Log.Information("Configuring console host ({ApplicationContext})...", appName);
var host = Host.CreateDefaultBuilder(args)
.UseConsoleLifetime(opts => opts.SuppressStatusMessages = true)
.ConfigureServices((hostContext, services) =>
{
services
.AddHostedService<EventRehydratorService>()
}).Build();
Log.Information("Starting console host ({ApplicationContext})...", appName);
await host.StartAsync();
await host.StopAsync();
}
catch (Exception ex)
{
Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", appName);
Environment.Exit(-1);
}
finally
{
Log.CloseAndFlush();
}
Environment.Exit(1);
}
EventRehydatorService 实现 IHostedService
internal class EventRehydratorService : IHostedService
{
private readonly IHostApplicationLifetime appLifetime;
private readonly IConfiguration configuration;
public IEventSourceService EventSourceService { get; }
public IDocumentStore Store { get; }
public EventRehydratorService(
IHostApplicationLifetime appLifetime,
IEventSourceService eventSourceService,
IDocumentStore store,
IConfiguration configuration)
{
this.appLifetime = appLifetime;
EventSourceService = eventSourceService;
Store = store;
this.configuration = configuration;
}
public Task StartAsync(CancellationToken cancellationToken)
{
appLifetime.ApplicationStopping.Register(OnStopping);
appLifetime.ApplicationStopped.Register(OnStopped);
return Task.CompletedTask;
}
private void OnStopping()
{
Log.Information("OnStopping has been called.");
}
private void OnStopped()
{
Log.Information("OnStopped has been called.");
}
public Task StopAsync(CancellationToken cancellationToken)
{
appLifetime.StopApplication();
return Task.CompletedTask;
}
}
}
Docker 文件:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["Shophattan.EventRehydrator/EventRehydrator.csproj", "Shophattan.EventRehydrator/"]
COPY ["Common/Shophattan.Common/Shophattan.Common.csproj", "Common/Shophattan.Common/"]
COPY ["RavenDB.DependencyInjection/RavenDB.DependencyInjection.csproj", "RavenDB.DependencyInjection/"]
RUN dotnet restore "Shophattan.EventRehydrator/EventRehydrator.csproj"
COPY . .
WORKDIR "/src/Shophattan.EventRehydrator"
RUN dotnet build "EventRehydrator.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "EventRehydrator.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "EventRehydrator.dll"]
调用了所有事件,但容器仍然存在 运行。这是 Kubernetes CronJob 的一个问题,因为作业永远不会完成。我试图终止当前进程,在 OnStopped 方法中抛出异常 Environment.Exit() 但 docker 从未完成。不确定我做错了什么?
想通了 - 简单到以零退出。出于某种原因,我认为它应该是一个正数。
Environment.Exit(0);
现在作业成功完成:
NAME COMPLETIONS DURATION AGE
dev-eventrehydrator-1586018400 1/1 3s 15m
我有一个 dotnet Core 3.1 应用程序,在 Program.cs
中创建了以下主机 public static async Task Main(string[] args)
{
var configuration = ConfigurationFactory.CreateConfiguration();
var appName = configuration.GetAppName();
Log.Logger = configuration.CreateSerilogLogger();
try
{
Log.Information("Configuring console host ({ApplicationContext})...", appName);
var host = Host.CreateDefaultBuilder(args)
.UseConsoleLifetime(opts => opts.SuppressStatusMessages = true)
.ConfigureServices((hostContext, services) =>
{
services
.AddHostedService<EventRehydratorService>()
}).Build();
Log.Information("Starting console host ({ApplicationContext})...", appName);
await host.StartAsync();
await host.StopAsync();
}
catch (Exception ex)
{
Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", appName);
Environment.Exit(-1);
}
finally
{
Log.CloseAndFlush();
}
Environment.Exit(1);
}
EventRehydatorService 实现 IHostedService
internal class EventRehydratorService : IHostedService
{
private readonly IHostApplicationLifetime appLifetime;
private readonly IConfiguration configuration;
public IEventSourceService EventSourceService { get; }
public IDocumentStore Store { get; }
public EventRehydratorService(
IHostApplicationLifetime appLifetime,
IEventSourceService eventSourceService,
IDocumentStore store,
IConfiguration configuration)
{
this.appLifetime = appLifetime;
EventSourceService = eventSourceService;
Store = store;
this.configuration = configuration;
}
public Task StartAsync(CancellationToken cancellationToken)
{
appLifetime.ApplicationStopping.Register(OnStopping);
appLifetime.ApplicationStopped.Register(OnStopped);
return Task.CompletedTask;
}
private void OnStopping()
{
Log.Information("OnStopping has been called.");
}
private void OnStopped()
{
Log.Information("OnStopped has been called.");
}
public Task StopAsync(CancellationToken cancellationToken)
{
appLifetime.StopApplication();
return Task.CompletedTask;
}
}
}
Docker 文件:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["Shophattan.EventRehydrator/EventRehydrator.csproj", "Shophattan.EventRehydrator/"]
COPY ["Common/Shophattan.Common/Shophattan.Common.csproj", "Common/Shophattan.Common/"]
COPY ["RavenDB.DependencyInjection/RavenDB.DependencyInjection.csproj", "RavenDB.DependencyInjection/"]
RUN dotnet restore "Shophattan.EventRehydrator/EventRehydrator.csproj"
COPY . .
WORKDIR "/src/Shophattan.EventRehydrator"
RUN dotnet build "EventRehydrator.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "EventRehydrator.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "EventRehydrator.dll"]
调用了所有事件,但容器仍然存在 运行。这是 Kubernetes CronJob 的一个问题,因为作业永远不会完成。我试图终止当前进程,在 OnStopped 方法中抛出异常 Environment.Exit() 但 docker 从未完成。不确定我做错了什么?
想通了 - 简单到以零退出。出于某种原因,我认为它应该是一个正数。
Environment.Exit(0);
现在作业成功完成:
NAME COMPLETIONS DURATION AGE
dev-eventrehydrator-1586018400 1/1 3s 15m