.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
相关产品推荐
相关产品推荐

