在 ASP.NET Core 中,健康检查(Health Checks)是监控应用程序及其依赖服务(如数据库、缓存、外部 API)运行状态的核心机制。它通过 HTTP 端点暴露应用的健康状况,供容器编排器(如 Kubernetes)、负载均衡器或运维人员使用。
基础配置:启用健康检查中间件
要启用健康检查,需要在 Program.cs 中注册服务并映射端点。默认情况下,如果应用能响应请求,则视为 Healthy。
cs
var builder = WebApplication.CreateBuilder(args);
// 1. 注册健康检查服务
builder.Services.AddHealthChecks();
var app = builder.Build();
// 2. 映射健康检查端点
// 默认返回纯文本状态 (Healthy/Unhealthy/Degraded)
app.MapHealthChecks("/health");
app.Run();
自定义健康检查逻辑
通过实现 IHealthCheck 接口,可以定义复杂的业务逻辑或依赖项检查。以下示例使用随机数模拟三种健康状态(Healthy, Degraded, Unhealthy),展示如何处理上下文和取消令牌。
步骤:
- 创建实现 IHealthCheck 的类。
- 在 CheckHealthAsync 方法中执行检查逻辑。
- 返回 HealthCheckResult。
cs
using Microsoft.Extensions.Diagnostics.HealthChecks;
public class RandomHealthCheck : IHealthCheck
{
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken = default)
{
// 模拟耗时操作,支持取消令牌
// 在实际场景中,这里可能是数据库连接测试或API调用
var random = new Random().Next(0, 3);
return Task.FromResult(random switch
{
0 => HealthCheckResult.Healthy("服务运行正常"),
1 => HealthCheckResult.Degraded("服务性能下降,但可用"),
_ => HealthCheckResult.Unhealthy("服务不可用")
});
}
}
注册自定义检查:
builder.Services.AddHealthChecks()
.AddCheck<RandomHealthCheck>("random-check");
改变响应状态码
默认情况下,Healthy 返回 200,Unhealthy 返回 503,Degraded 返回 200。可以通过 HealthCheckOptions 自定义这些状态码,以便负载均衡器或监控系统根据特定状态码采取不同行动。
cs
app.MapHealthChecks("/health-status", new HealthCheckOptions
{
// 自定义状态码映射
ResultStatusCodes =
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Degraded] = StatusCodes.Status200OK, // 降级仍视为可用,但可标记
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
}
});
定制响应内容
默认的纯文本响应信息量有限。通常我们需要返回 JSON 格式的详细报告,包含每个检查项的名称、状态、描述和执行时间。这需要通过 ResponseWriter 实现。
自定义 JSON 响应写入器:
cs
using System.Text.Json;
using Microsoft.Extensions.Diagnostics.HealthChecks;
public static class HealthCheckResponseWriter
{
public static Task WriteJsonResponse(HttpContext context, HealthReport report)
{
context.Response.ContentType = "application/json";
var result = JsonSerializer.Serialize(new
{
status = report.Status.ToString(),
totalDuration = report.TotalDuration,
checks = report.Entries.Select(e => new
{
name = e.Key,
status = e.Value.Status.ToString(),
description = e.Value.Description,
duration = e.Value.Duration,
exception = e.Value.Exception?.Message
})
}, new JsonSerializerOptions { WriteIndented = true });
return context.Response.WriteAsync(result);
}
}
应用自定义响应:
cs
app.MapHealthChecks("/health-json", new HealthCheckOptions
{
ResponseWriter = HealthCheckResponseWriter.WriteJsonResponse
});
发布健康报告
除了通过 HTTP 端点被动查询,ASP.NET Core 还支持主动发布健康报告。通过实现 IHealthCheckPublisher 接口,可以将健康状态定期推送到控制台、数据库、日志系统或监控平台(如 Prometheus)。
自定义发布器示例(输出到控制台):
cs
using Microsoft.Extensions.Diagnostics.HealthChecks;
public class ConsoleHealthCheckPublisher : IHealthCheckPublisher
{
public Task PublishAsync(HealthReport report, CancellationToken cancellationToken)
{
Console.WriteLine($"[{DateTime.Now}] Health Status: {report.Status}");
foreach (var entry in report.Entries)
{
Console.WriteLine($" - {entry.Key}: {entry.Value.Status} ({entry.Value.Description})");
}
return Task.CompletedTask;
}
}
注册发布器:
cs
builder.Services.AddHealthChecks()
.AddCheck<RandomHealthCheck>("random-check");
// 添加发布器服务
builder.Services.AddHealthChecksPublisher<ConsoleHealthCheckPublisher>();
// 配置发布频率(默认30秒)
builder.Services.Configure<HealthCheckPublisherOptions>(options =>
{
options.Period = TimeSpan.FromSeconds(10);
});
注意:AddHealthChecksPublisher 需要确保后台主机服务已启动,通常在 Web 应用中自动处理。
可视化健康检查界面
为了更直观地监控健康状态,可以使用第三方库 AspNetCore.HealthChecks.UI。它提供一个漂亮的 Web UI,展示历史健康数据和实时状态。
步骤:
安装 NuGet 包:
dotnet add package AspNetCore.HealthChecks.UI
dotnet add package AspNetCore.HealthChecks.UI.InMemory.Storage
生产环境建议使用 SQL Server 或 SQLite 存储
dotnet add package AspNetCore.HealthChecks.UI.SqlServer.Storage
配置服务和中间件:
cs
using HealthChecks.UI.Client;
var builder = WebApplication.CreateBuilder(args);
// 添加健康检查服务
builder.Services.AddHealthChecks()
.AddSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))
.AddRedis(builder.Configuration.GetConnectionString("Redis"));
// 添加 Health Checks UI 服务
builder.Services.AddHealthChecksUI(setupSettings =>
{
setupSettings.SetEvaluationTimeInSeconds(15); // 每15秒评估一次
})
.AddInMemoryStorage(); // 使用内存存储历史记录
var app = builder.Build();
// 启用标准健康检查端点(UI 需要此端点获取数据)
app.UseHealthChecks("/health", new HealthCheckOptions
{
Predicate = _ => true,
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
// 启用 Health Checks UI 中间件
app.UseHealthChecksUI(options =>
{
options.UIPath = "/health-ui"; // 访问 UI 的路径
options.ApiPath = "/health-ui-api"; // UI 获取数据的 API 路径
});
app.Run();
访问界面:
启动应用后,浏览器访问 https://localhost:<port>/health-ui 即可看到可视化的健康检查 dashboard。
总结
| 功能模块 | 关键组件/接口 | 用途 |
|---|---|---|
| 基础检查 | AddHealthChecks(), MapHealthChecks() |
暴露 /health 端点,返回基本状态 |
| 自定义逻辑 | IHealthCheck |
实现具体的业务或依赖项检查逻辑 |
| 状态码定制 | HealthCheckOptions.ResultStatusCodes |
修改 HTTP 状态码以适配负载均衡策略 |
| 响应定制 | HealthCheckOptions.ResponseWriter |
返回 JSON 等详细格式的诊断信息 |
| 报告发布 | IHealthCheckPublisher |
主动推送健康状态到日志、DB 或监控系统 |
| 可视化 UI | AspNetCore.HealthChecks.UI |
提供 Web 界面查看实时和历史健康数据 |
通过组合上述功能,可以构建一个健壮、可观测且易于维护的健康检查系统,确保应用在生产环境中的高可用性。