.NET Core 健康检查

在 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 界面查看实时和历史健康数据

通过组合上述功能,可以构建一个健壮、可观测且易于维护的健康检查系统,确保应用在生产环境中的高可用性。

相关推荐
初阳7851 小时前
【基于Qt5仿音乐播放器(四)】——播放控制
1024程序员节
2601_958736991 小时前
虚拟电商新手怎么做?从零到第一单的完整流程
1024程序员节
wjkjpcba1 小时前
割草机器人主控板PCBA加工厂家怎么选?MCU贴装、传感器接口与检测
1024程序员节·smt贴片加工·pcba贴片加工厂
茉莉玫瑰花茶1 小时前
线性代数 [ 线性组合·张成的空间与基 ]
线性代数·math·1024程序员节
这是谁的博客?1 小时前
AI 芯片存算一体(PIM/CIM)架构深度解析:从冯·诺依曼瓶颈与近存计算到 RRAM 模拟矩阵乘的 LLM 推理显存墙突破原理
ai·pim·1024程序员节·cim·存算一体·hbm-pim·lpddr5x-pim
WebKoalaBoy1 小时前
一台电脑同时配置多个 Git 账号:从原理到实战
1024程序员节
啊哈一半醒1 小时前
Redis 三大缓存问题:缓存穿透、缓存击穿、缓存雪崩
运维·redis·1024程序员节
啵啵啵鱼1 小时前
用 Claude Code 重构遗留系统:从评估到落地的完整实践
数据结构·1024程序员节
I Am a robert girl1 小时前
当扩散编辑器“看不见”参考图:从 RefGAP 拆解参考注意力分配问题
计算机视觉·注意力机制·扩散模型·1024程序员节·参考引导编辑·refgap·免训练方法