.NET Core Workerservice - 如何在没有 HTTP 的情况下提供运行状况检查端点?

sil*_*ent 11 c# kubernetes asp.net-core

我构建了一个在 kubernetes 上运行的 ASP.NET Core Worker Service(它处理队列中的消息)。由于它是后台服务,因此目前没有任何 HTTP 端点。现在我想向其中添加 k8s 的运行状况/活跃性端点 - 最好利用.NET Core 标准运行状况检查

所以我的问题是:有没有一种方法可以公开这些运行状况检查,而无需以 k8s 可以使用它们的方式(TCP 或通用命令)增加 HTTP 端点的开销?任何指向示例的指针都会很棒!谢谢!

sil*_*ent 9

感谢 @pinkfloydx33 的指点,我能够构建这个解决方案:

程序.cs

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
    .ConfigureServices((hostContext, services) =>
    {
        services.AddHealthChecks() // Register some real health check here ==>
            .AddCheck("test", () => DateTime.UtcNow.Minute % 2 == 0 ? HealthCheckResult.Healthy() : HealthCheckResult.Unhealthy());
        services.AddSingleton<IHealthCheckPublisher, HealthCheckPublisher>();
        services.Configure<HealthCheckPublisherOptions>(options =>
        {
            options.Delay = TimeSpan.FromSeconds(5);
            options.Period = TimeSpan.FromSeconds(20);
        });

        // Register the actual message processor service
        services.AddHostedService<QueueProcessorService>();
    })
Run Code Online (Sandbox Code Playgroud)

HealthCheckPublisher.cs

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

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

    /// <summary>
    /// Creates / touches a file on the file system to indicate "healtyh" (liveness) state of the pod
    /// Deletes the files to indicate "unhealthy"
    /// The file will then be checked by k8s livenessProbe
    /// </summary>
    /// <param name="report"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public Task PublishAsync(HealthReport report, CancellationToken cancellationToken)
    {
        var fileExists = _prevStatus == HealthStatus.Healthy;

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

        _prevStatus = report.Status;

        return Task.CompletedTask;
    }
}
Run Code Online (Sandbox Code Playgroud)

k8s部署.yaml(原始来源:https://medium.com/spire-labs/utilizing-kubernetes-liveness-and-readiness-probes-to-automatically-recover-from-failure-2fe0314f2b2e

感谢@zimbres 指出了活性探针中的缺陷。现在这是更新版本:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
    .ConfigureServices((hostContext, services) =>
    {
        services.AddHealthChecks() // Register some real health check here ==>
            .AddCheck("test", () => DateTime.UtcNow.Minute % 2 == 0 ? HealthCheckResult.Healthy() : HealthCheckResult.Unhealthy());
        services.AddSingleton<IHealthCheckPublisher, HealthCheckPublisher>();
        services.Configure<HealthCheckPublisherOptions>(options =>
        {
            options.Delay = TimeSpan.FromSeconds(5);
            options.Period = TimeSpan.FromSeconds(20);
        });

        // Register the actual message processor service
        services.AddHostedService<QueueProcessorService>();
    })
Run Code Online (Sandbox Code Playgroud)