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

.NET如何在控制器或类中动态添加/移除HealthCheck

动态添加/移除ASP.NET Core健康检查的实现方式

我在startup.cs中使用以下代码块配置健康检查:

var bldr = builder.Services
  .AddHealthChecks();
foreach (var url in urls)
{
    bldr = bldr.AddCheck(
        url,
      new HealhCheck(url)); // 注:原代码拼写错误,应为HealthCheck
}

但我需要在控制器或其他类中动态添加更多HealthCheck或移除已有HealthCheck,请问是否有可行的实现方式?

ASP.NET Core默认的健康检查注册是启动时一次性完成的,运行时无法直接修改已注册的检查项。要实现动态管理,需要自己封装一个可维护的健康检查容器,再通过一个聚合检查来代理执行这些动态项。

步骤1:实现动态健康检查管理器

写一个线程安全的管理器,用来维护健康检查集合,提供添加、移除和获取方法:

public class DynamicHealthCheckManager
{
    private readonly ConcurrentDictionary<string, IHealthCheck> _healthChecks = new();

    // 添加健康检查
    public bool AddHealthCheck(string name, IHealthCheck healthCheck)
    {
        return _healthChecks.TryAdd(name, healthCheck);
    }

    // 移除健康检查
    public bool RemoveHealthCheck(string name)
    {
        return _healthChecks.TryRemove(name, out _);
    }

    // 获取所有健康检查
    public IEnumerable<KeyValuePair<string, IHealthCheck>> GetAllHealthChecks()
    {
        return _healthChecks.ToList();
    }
}

步骤2:实现聚合健康检查

这个检查会遍历管理器中的所有动态检查,逐个执行并汇总结果:

public class AggregateDynamicHealthCheck : IHealthCheck
{
    private readonly DynamicHealthCheckManager _manager;

    public AggregateDynamicHealthCheck(DynamicHealthCheckManager manager)
    {
        _manager = manager;
    }

    public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        var results = new List<(string Name, HealthCheckResult Result)>();

        foreach (var (name, check) in _manager.GetAllHealthChecks())
        {
            try
            {
                var result = await check.CheckHealthAsync(context, cancellationToken);
                results.Add((name, result));
            }
            catch (Exception ex)
            {
                results.Add((name, HealthCheckResult.Unhealthy($"检查执行失败: {ex.Message}", ex)));
            }
        }

        // 汇总结果:存在失败项则返回不健康,全部正常则返回健康
        if (results.Any(r => r.Result.Status == HealthStatus.Unhealthy))
        {
            return HealthCheckResult.Unhealthy("部分动态健康检查失败", null, new Dictionary<string, object>
            {
                ["checkResults"] = results.ToDictionary(r => r.Name, r => r.Result.Status.ToString())
            });
        }

        return HealthCheckResult.Healthy("所有动态健康检查正常");
    }
}

步骤3:在Startup中注册服务

把管理器和聚合检查注册到DI容器,同时将聚合检查添加到健康检查系统:

// 注册动态健康检查管理器(单例)
builder.Services.AddSingleton<DynamicHealthCheckManager>();

// 注册聚合健康检查,并添加到健康检查系统
builder.Services.AddHealthChecks()
    .AddCheck<AggregateDynamicHealthCheck>("dynamic_health_checks");

// 保留原来的静态检查配置
foreach (var url in urls)
{
    builder.Services.AddHealthChecks().AddCheck(url, new HealthCheck(url));
}

步骤4:在控制器中动态管理健康检查

注入DynamicHealthCheckManager,实现添加和移除的接口:

[ApiController]
[Route("api/health/checks")]
public class HealthCheckManagementController : ControllerBase
{
    private readonly DynamicHealthCheckManager _manager;

    public HealthCheckManagementController(DynamicHealthCheckManager manager)
    {
        _manager = manager;
    }

    [HttpPost("add")]
    public IActionResult AddHealthCheck([FromQuery] string name, [FromQuery] string url)
    {
        var check = new HealthCheck(url); // 使用你自己的HealthCheck实现
        var added = _manager.AddHealthCheck(name, check);
        return added ? Ok($"健康检查 {name} 添加成功") : BadRequest($"健康检查 {name} 已存在");
    }

    [HttpDelete("remove")]
    public IActionResult RemoveHealthCheck([FromQuery] string name)
    {
        var removed = _manager.RemoveHealthCheck(name);
        return removed ? Ok($"健康检查 {name} 移除成功") : NotFound($"健康检查 {name} 不存在");
    }
}

注意事项

  • 确保你的HealthCheck类正确实现IHealthCheck接口
  • 动态添加的检查会在每次健康检查请求时执行,无需重启应用
  • 若需要持久化动态检查配置,可将管理器的集合与数据库绑定,启动时从数据库加载已有检查

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:45:31