.Net Core Worker Service中进行健康检查的最佳方法

在.NET Core Worker Service中实现运行状况检查的最佳方法是什么?

该服务将在docker内部运行,并且需要能够检查该服务的运行状况。

a946527083 回答:.Net Core Worker Service中进行健康检查的最佳方法

我认为将 SDK 更改为 Microsoft.NET.Sdk.Web 不值得。你会因为一次健康检查而包含额外的中间件吗?不用谢...

您可以做的是使用不同的协议,如 TCP。

总体思路是:

  1. 创建一个单独的后台服务来创建一个 TCP 服务器(看看TcpListener.cs
  2. 当您收到请求时,您有两种选择:如果应用程序运行良好,则接受 TCP 连接,否则拒绝它。
  3. 如果您使用容器,您的编排器应该可以选择通过 TCP 调用它(在 k8s 中有一个属性 tcpSocket

如果您需要更详细的信息,您可以查看:Monitoring Health of ASP.NET Core Background Services With TCP Probes on Kubernetes

干杯!

,

执行此操作的另一种方法是实现IHealthCheckPublisher

这种方法的好处是能够重用您现有的IHealthCheck或与依赖IHealthCheck接口(例如this one)的第三方库进行集成。

尽管您仍将Microsoft.NET.Sdk.Web定位为SDK,但不需要添加任何asp.net细节。

这里是一个例子:

public static IHostBuilder CreateHostBuilder(string[] args)
{
  return Host
    .CreateDefaultBuilder(args)
    .ConfigureServices((hostContext,services) =>
    {
      services
        .AddHealthChecks()
        .AddCheck<RedisHealthCheck>("redis_health_check")
        .AddCheck<RfaHealthCheck>("rfa_health_check");

      services.AddSingleton<IHealthCheckPublisher,HealthCheckPublisher>();
      services.Configure<HealthCheckPublisherOptions>(options =>
      {
        options.Delay = TimeSpan.FromSeconds(5);
        options.Period = TimeSpan.FromSeconds(5);
      });
    });
}

public class HealthCheckPublisher : IHealthCheckPublisher
{
  private readonly string _fileName;
  private HealthStatus _prevStatus = HealthStatus.Unhealthy;

  public HealthCheckPublisher()
  {
    _fileName = Environment.GetEnvironmentVariable(EnvVariableNames.DOCKER_HEALTHCHECK_FILEPATH) ??
                Path.GetTempFileName();
  }

  public Task PublishAsync(HealthReport report,CancellationToken cancellationToken)
  {
    // AWS will check if the file exists inside of the container with the command
    // test -f $DOCKER_HEALTH_CHECK_FILEPATH

    var fileExists = _prevStatus == HealthStatus.Healthy;

    if (report.Status == HealthStatus.Healthy)
    {
      if (!fileExists)
      {
        using var _ = File.Create(_fileName);
      }
    }
    else if (fileExists)
    {
      File.Delete(_fileName);
    }

    _prevStatus = report.Status;

    return Task.CompletedTask;
  }
}
,

要做到这一点,我将Microsoft.NET.Sdk.Web添加到了Worker中,然后将一个Web主机配置为与Worker一起运行:

Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(builder =>
    {
        builder.UseStartup<Startup>();
    })
    .ConfigureServices((hostContext,services) =>
    {
        services.AddHostedService<Worker>();
        services.AddLogging(builder =>
            builder
                .AddDebug()
                .AddConsole()
        );
    });

完成此操作后,剩下要做的就是map the health check endpoint,就像通常使用ASP.NET Core一样。

,

我认为您还应该考虑保留Microsoft.NET.Sdk.Worker。

不要仅仅因为运行状况检查而更改整个SDK。

然后,您可以创建一个backgroundservice(就像main worker一样),以便更新文件以写入例如当前时间戳。后台健康检查工作者的示例为:

public class HealthCheckWorker : BackgroundService
{
    private readonly int _intervalSec;
    private readonly string _healthCheckFileName;

    public HealthCheckWorker(string healthCheckFileName,int intervalSec)
    {
        this._intervalSec = intervalSec;
        this._healthCheckFileName = healthCheckFileName;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (true)
        {
            File.WriteAllText(this._healthCheckFileName,DateTime.UtcNow.ToString());
            await Task.Delay(this._intervalSec * 1000,stoppingToken);
        }
    }
}

然后,您可以添加如下扩展方法:

public static class HealthCheckWorkerExtensions
{
    public static void AddHealthCheck(this IServiceCollection services,string healthCheckFileName,int intervalSec)
    {
        services.AddHostedService<HealthCheckWorker>(x => new HealthCheckWorker(healthCheckFileName,intervalSec));
    }
}

您可以通过此服务添加健康检查支持

.ConfigureServices(services =>
{
    services.AddHealthCheck("hc.txt",5);
})
本文链接:https://www.f2er.com/3136301.html

大家都在问