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

请教:如何在Hosted Service上实现.NET Core Health Checks?

针对Hosted Service实现健康检查的最佳实践

我之前也遇到过类似的困惑,数据库、Event Store这类组件的健康检查有现成方案,但Hosted Service因为是自定义的后台逻辑,需要我们自己适配。核心思路是让Hosted Service暴露关键运行状态,再结合.NET自带的健康检查框架来实现监控。下面分享几个实践下来靠谱的方法:

1. 基础方案:检查Hosted Service的运行状态

如果你的Hosted Service基于BackgroundService实现,首先可以在服务类里添加状态属性,标记服务是否正常运行:

public class MyBackgroundWorker : BackgroundService
{
    // 暴露运行状态
    public bool IsRunning { get; private set; }
    private readonly ILogger<MyBackgroundWorker> _logger;

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

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        IsRunning = true;
        try
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                // 你的后台任务逻辑
                _logger.LogInformation("Worker executing at {Time}", DateTimeOffset.Now);
                await Task.Delay(2000, stoppingToken);
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Worker encountered an unexpected error");
            IsRunning = false;
            // 可根据需求添加异常恢复逻辑
        }
        finally
        {
            IsRunning = false;
        }
    }
}

接下来创建自定义健康检查类,注入Hosted Service并检查状态:

public class WorkerHealthCheck : IHealthCheck
{
    private readonly MyBackgroundWorker _worker;

    public WorkerHealthCheck(MyBackgroundWorker worker)
    {
        _worker = worker;
    }

    public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        if (_worker.IsRunning)
        {
            return Task.FromResult(HealthCheckResult.Healthy("Background worker is running normally"));
        }
        else
        {
            return Task.FromResult(HealthCheckResult.Unhealthy("Background worker has stopped unexpectedly"));
        }
    }
}

最后在Program.cs里注册健康检查并映射端点:

var builder = WebApplication.CreateBuilder(args);

// 注册Hosted Service
builder.Services.AddHostedService<MyBackgroundWorker>();
// 注册自定义健康检查
builder.Services.AddHealthChecks()
    .AddCheck<WorkerHealthCheck>("background_worker");

var app = builder.Build();

// 映射健康检查端点
app.MapHealthChecks("/health");

app.Run();

2. 进阶方案:监控业务级状态指标

如果你的Hosted Service处理有状态任务(比如消息队列消费、数据同步),可以扩展状态属性,监控任务积压、处理延迟等业务指标,让健康检查更有价值:

比如在Worker类里添加任务积压计数:

public class QueueProcessingWorker : BackgroundService
{
    public bool IsRunning { get; private set; }
    public int PendingMessages { get; private set; }
    private readonly IMessageQueue _queue;
    private readonly ILogger<QueueProcessingWorker> _logger;

    // 构造函数注入队列服务...

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        IsRunning = true;
        while (!stoppingToken.IsCancellationRequested)
        {
            PendingMessages = await _queue.GetPendingCountAsync(stoppingToken);
            
            if (PendingMessages > 0)
            {
                var message = await _queue.DequeueAsync(stoppingToken);
                // 处理消息逻辑
            }

            await Task.Delay(500, stoppingToken);
        }
        IsRunning = false;
    }
}

然后在健康检查里根据阈值判断健康状态:

public class QueueWorkerHealthCheck : IHealthCheck
{
    private readonly QueueProcessingWorker _worker;
    // 自定义积压阈值
    private const int BacklogThreshold = 100;

    public QueueWorkerHealthCheck(QueueProcessingWorker worker)
    {
        _worker = worker;
    }

    public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        if (!_worker.IsRunning)
        {
            return Task.FromResult(HealthCheckResult.Unhealthy("Queue processing worker is stopped"));
        }

        if (_worker.PendingMessages > BacklogThreshold)
        {
            // 返回降级状态,提示有任务积压
            return Task.FromResult(HealthCheckResult.Degraded(
                "Queue worker has a message backlog",
                null,
                new Dictionary<string, object> { { "pending_messages", _worker.PendingMessages } }));
        }

        return Task.FromResult(HealthCheckResult.Healthy(
            "Queue worker is processing messages normally",
            new Dictionary<string, object> { { "pending_messages", _worker.PendingMessages } }));
    }
}

3. 第三方Hosted Service的集成

如果用的是第三方提供的Hosted Service(比如Quartz调度、Hangfire后台任务),通常官方会提供对应的健康检查集成包,直接引用即可:

比如Quartz的健康检查集成:

builder.Services.AddQuartz(q => { /* Quartz配置 */ });
builder.Services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
// 添加Quartz健康检查
builder.Services.AddHealthChecks()
    .AddQuartzHealthCheck();

注意事项

  • 健康检查逻辑要轻量快速,避免在检查中执行耗时操作,否则会拖慢健康端点的响应
  • Hosted Service默认是单例生命周期,注入到健康检查类时要保持生命周期一致
  • 可以结合监控工具(比如Prometheus+Grafana),将健康检查的指标可视化,方便实时监控

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 20:02:26