You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6后台服务在ECS Fargate中StopAsync未触发问题排查

问题

我使用.NET 6开发了一个后台服务,预期在本地通过CTRL+C停止服务,以及在AWS上停止ECS任务时,StopAsync()方法会被调用。目前本地运行时该方法正常触发,但采用Fargate启动类型的ECS任务停止时,StopAsync()方法从未被执行。

相关代码实现如下:

Worker类代码

public class Worker : BackgroundService
{
   private readonly ILogger<Worker> _logger;

   public Worker(ILogger<Worker> logger)
   {
       _logger = logger;
   }

   protected override async Task ExecuteAsync(CancellationToken stoppingToken)
   {
       while (!stoppingToken.IsCancellationRequested)
       {
           _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
           await Task.Delay(1000, stoppingToken);
       }
   }

   public override Task StartAsync(CancellationToken cancellationToken)
   {
       _logger.LogInformation("StartAsync called");
       return Task.CompletedTask;
   }

   public override Task StopAsync(CancellationToken cancellationToken)
   {
        _logger.LogInformation("StopAsync called");
         return Task.CompletedTask;
   }
}

Host构建代码

var host = new HostBuilder()
        .ConfigureServices(s => s.AddHostedService<Worker>())
        .ConfigureLogging(l => l.AddConsole());
 await host.RunConsoleAsync();

Dockerfile

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
 WORKDIR /app
 COPY ./ ./
 RUN dotnet publish -c Release -o out

 FROM mcr.microsoft.com/dotnet/aspnet:6.0
 WORKDIR /app
 COPY --from=build-env /app/out .
 ENTRYPOINT ["dotnet", "TestService.dll"]

根据微软官方文档,RunConsoleAsync应当处理SIGTERM信号,但当前ECS Fargate环境下未生效,请问我的代码存在什么问题?

解决方案
  • RunConsoleAsync的场景局限性:RunConsoleAsync是专门为本地控制台运行设计的API,在容器化环境(如Fargate)中不会自动注册SIGTERM信号处理逻辑。应该改用通用主机的RunAsync方法,同时使用Host.CreateDefaultBuilder()来初始化主机——它会自动配置容器环境下的停机信号捕获逻辑。修改后的Host构建代码如下:
var host = Host.CreateDefaultBuilder()
    .ConfigureServices(s => s.AddHostedService<Worker>())
    .ConfigureLogging(l => l.AddConsole())
    .Build();

await host.RunAsync();
  • StartAsync未调用基类方法:当前StartAsync直接返回Task.CompletedTask,跳过了基类BackgroundService.StartAsync的初始化逻辑,导致服务未正确注册到主机生命周期管理流程中,停机时无法触发StopAsync。修改StartAsync方法:
public override async Task StartAsync(CancellationToken cancellationToken)
{
    _logger.LogInformation("StartAsync called");
    await base.StartAsync(cancellationToken);
}
  • 验证ECS停止策略配置:Fargate默认发送SIGTERM后等待30秒再发送SIGKILL,如果你的StopAsync有耗时逻辑,需要在ECS任务定义中调整停止超时时间,避免进程被强制杀死导致StopAsync未执行完成。

内容的提问来源于stack exchange,提问作者Venkatesh Venky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 13:32:45