如何在.NET Framework 4.8的ASP.NET MVC中集成HealthChecks组件
.NET Framework 4.8 ASP.NET MVC 集成
Microsoft.Extensions.Diagnostics.HealthChecks 实现方案 Microsoft.Extensions.Diagnostics.HealthChecks 从2.2版本开始就支持.NET Standard 2.0,而.NET Framework 4.8原生兼容.NET Standard 2.0,完全可以正常集成,不需要自己重写健康检查逻辑,只是因为.NET Framework版MVC没有内置Core的DI和端点路由,需要手动补几个适配步骤。
步骤1:安装对应版本的NuGet包
注意:7.0及以上版本的Microsoft.Extensions.*系列包不再支持.NET Standard 2.0,必须统一选择6.0.x LTS版本安装,否则会出现依赖冲突或运行时异常:
- 核心包:
Microsoft.Extensions.Diagnostics.HealthChecks(6.0.x版本) - DI依赖包:
Microsoft.Extensions.DependencyInjection(6.0.x版本) - 扩展检查项按需安装:比如SQL Server检查装
Microsoft.Extensions.Diagnostics.HealthChecks.SqlServer、Redis检查装对应6.0.x版本的包即可,所有扩展包都要和核心包版本保持一致。
步骤2:启动阶段注册健康检查服务
ASP.NET MVC 5(.NET Framework)没有内置依赖注入容器,需要在全局启动点Global.asax.cs中手动构建服务容器,注册健康检查相关服务,代码示例:
public class MvcApplication : HttpApplication { // 全局存服务提供者,后续接口中调用 public static IServiceProvider ServiceProvider { get; private set; } protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); // 初始化DI容器,注册健康检查 var services = new ServiceCollection(); services.AddHealthChecks() // 注册基础自检项 .AddCheck("self_check", () => HealthCheckResult.Healthy("实例运行正常"), tags: new[] { "live" }) // 按需追加其他检查项示例: // .AddSqlServer(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString, name: "db_check", tags: new[] { "ready" }) // .AddRedis(ConfigurationManager.AppSettings["RedisConnection"], name: "redis_check", tags: new[] { "ready" }) ; ServiceProvider = services.BuildServiceProvider(); } }
如果项目本身已经集成了Autofac、Unity等第三方DI容器,直接把健康检查的服务注册到现有容器即可,不需要单独维护ServiceProvider。
步骤3:添加健康检查访问端点
因为.NET Framework版MVC没有Core的端点路由中间件,最简便的方式是新增一个匿名可访问的Controller作为健康检查出口,记得跳过全局的权限拦截、日志拦截逻辑:
[AllowAnonymous] public class HealthController : Controller { private readonly HealthCheckService _healthCheckService; public HealthController() { // 从全局服务提供者获取健康检查服务实例,如果用第三方DI直接走构造注入即可 _healthCheckService = MvcApplication.ServiceProvider.GetRequiredService<HealthCheckService>(); } /// <summary> /// 基础存活检查,供负载均衡探活用 /// </summary> [Route("health/live")] public async Task<ActionResult> Live() { var report = await _healthCheckService.CheckHealthAsync(ct => Task.FromResult(ct.Tags.Contains("live"))); Response.StatusCode = report.Status == HealthStatus.Healthy ? 200 : 503; return Content(report.Status.ToString(), "text/plain"); } /// <summary> /// 就绪检查,检查所有依赖组件可用性 /// </summary> [Route("health/ready")] public async Task<ActionResult> Ready() { var report = await _healthCheckService.CheckHealthAsync(ct => Task.FromResult(ct.Tags.Contains("ready"))); Response.StatusCode = report.Status == HealthStatus.Healthy ? 200 : 503; // 结构化JSON返回,供监控系统采集 var result = new { status = report.Status.ToString(), totalDurationMs = report.TotalDuration.TotalMilliseconds, checks = report.Entries.Select(kv => new { name = kv.Key, status = kv.Value.Status.ToString(), desc = kv.Value.Description, durationMs = kv.Value.Duration.TotalMilliseconds, exception = kv.Value.Exception?.Message }) }; return Json(result, JsonRequestBehavior.AllowGet); } }
如果用了特性路由,上面的[Route]特性直接就能生效;如果没开特性路由,去RouteConfig.cs里加对应路由映射即可:
routes.MapRoute( name: "HealthLive", url: "health/live", defaults: new { controller = "Health", action = "Live" } ); routes.MapRoute( name: "HealthReady", url: "health/ready", defaults: new { controller = "Health", action = "Ready" } );
常见踩坑提示
- 所有
Microsoft.Extensions.*相关包版本必须严格统一为6.0.x,混装高版本会出现MissingMethodException、FileLoadException等运行时错误 - 健康检查逻辑不要写太重的操作,比如全表查询、大接口调用,否则探活超时会被负载均衡误判为实例异常
- 如果项目有全局异常过滤器、请求拦截器,记得把
/health/*路径加入白名单,避免拦截导致探活失败 - 不需要额外引入System.Text.Json包,用项目里现有的Newtonsoft.Json做序列化即可,兼容性更好
内容的提问来源于stack exchange,提问作者Prasad Patil
相关产品推荐
相关产品推荐

