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

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

相关推荐
Jeff-Tsai4 小时前
Day 19:定制层的范围与叠加粒度
.net·架构设计·erp·definition-driven
普通人65 小时前
WebGL与WebGPU入门指南
开发语言·webgl·1024程序员节
猫猫不是喵喵.1 天前
从0到1创建一个微服务项目
java·数据库·微服务·1024程序员节
Jeff-Tsai1 天前
Day 18:错误契约与用户可见消息
.net·架构设计·erp·definition-driven
IT规划师1 天前
HybridCache-缓存架构决策框架落地
架构·.net
Jeff-Tsai2 天前
Day 17:Connector 与调用端的职责收敛
.net·架构设计·erp·definition-driven
IT规划师3 天前
NET10 高并发架构契约与落地实现
架构·.net
公子小六3 天前
基于.NET的Windows窗体编程之WinForms数据持久化(1)
windows·microsoft·c#·.net·winforms
Jeff-Tsai3 天前
Day 16:JSON-RPC 2.0:协议选型与请求管道
.net·架构设计·erp·definition-driven
IT规划师3 天前
Redis 数据类型全解 - Stream 深度:Pending 回收、重试死信与消息队列选型(十一)
redis·.net