首页 > 解决方案 > 在 .NET Core Worker 服务中执行健康检查

问题描述

如何在 .NET Core Worker 服务中实现运行状况检查?

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

标签: c#docker.net-coreservice

解决方案


另一种方法是实现IHealthCheckPublisher.

这种方法的好处是能够重用您现有IHealthCheck的 s 或与依赖IHealthCheck接口的 3rd 方库集成(例如这个)。

尽管您仍然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;
  }
}

推荐阅读