当前位置: 首页 > news >正文

案例——从零开始搭建 ASP.NET Core 健康检查实例

1. 项目创建与基础设置

创建新项目

首先,创建一个新的 ASP.NET Core Web API 项目:

dotnet new webapi -n HealthCheckDemo
cd HealthCheckDemo

添加必要的 NuGet 包

添加健康检查相关的 NuGet 包:

dotnet add package Microsoft.AspNetCore.Diagnostics.HealthChecks
dotnet add package AspNetCore.HealthChecks.SqlServer  # 用于数据库健康检查
dotnet add package AspNetCore.HealthChecks.Redis     # 用于 Redis 健康检查

2. 健康检查原理解析

在深入代码之前,让我们先理解健康检查的核心概念:

  1. 健康检查服务:ASP.NET Core 提供了一个框架,用于报告应用程序及其依赖组件的健康状态
  2. 检查类型
    • 存活检查 (Liveness):应用程序是否正在运行
    • 就绪检查 (Readiness):应用程序是否准备好处理请求
    • 依赖检查:外部依赖(数据库、缓存等)是否可用
  3. 响应格式:健康检查端点返回一个 JSON 对象,包含整体状态和各个检查的详细结果

3. 完整代码实现

Program.cs 完整代码

using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using System.Text.Json;
using System.Text.Json.Serialization;var builder = WebApplication.CreateBuilder(args);// 添加服务到容器
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();// 1. 注册健康检查服务
builder.Services.AddHealthChecks()// 2. 添加一个简单的存活检查(总是健康).AddCheck("self", () => HealthCheckResult.Healthy("Application is running"), tags: new[] { "live" })// 3. 添加数据库健康检查(模拟).AddCheck("database", () => {// 模拟数据库检查var isHealthy = CheckDatabaseConnection();return isHealthy ? HealthCheckResult.Healthy("Database connection is OK") : HealthCheckResult.Unhealthy("Database connection failed");}, tags: new[] { "ready", "database" })// 4. 添加 Redis 健康检查(模拟).AddCheck("redis", () => {// 模拟 Redis 检查var isHealthy = CheckRedisConnection();return isHealthy ? HealthCheckResult.Healthy("Redis connection is OK") : HealthCheckResult.Unhealthy("Redis connection failed");}, tags: new[] { "ready", "redis" });// 模拟数据库连接检查方法
bool CheckDatabaseConnection()
{// 在实际应用中,这里会尝试连接到真实数据库// 这里我们模拟90%的成功率return new Random().NextDouble() > 0.1;
}// 模拟 Redis 连接检查方法
bool CheckRedisConnection()
{// 在实际应用中,这里会尝试连接到真实 Redis// 这里我们模拟80%的成功率return new Random().NextDouble() > 0.2;
}var app = builder.Build();// 配置 HTTP 请求管道
if (app.Environment.IsDevelopment())
{app.UseSwagger();app.UseSwaggerUI();
}app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();// 5. 配置健康检查端点// 综合健康检查端点(包含所有检查)
app.MapHealthChecks("/health", new HealthCheckOptions
{// 自定义响应格式ResponseWriter = async (context, report) =>{context.Response.ContentType = "application/json";var response = new{status = report.Status.ToString(),totalDuration = report.TotalDuration.ToString(),checks = report.Entries.Select(e => new{name = e.Key,status = e.Value.Status.ToString(),description = e.Value.Description,duration = e.Value.Duration.ToString()})};await context.Response.WriteAsync(JsonSerializer.Serialize(response, new JsonSerializerOptions { WriteIndented = true }));}
});// 存活检查端点(只包含快速的基本检查)
app.MapHealthChecks("/health/live", new HealthCheckOptions
{Predicate = check => check.Tags.Contains("live"),ResponseWriter = WriteHealthCheckResponse
});// 就绪检查端点(包含所有依赖检查)
app.MapHealthChecks("/health/ready", new HealthCheckOptions
{Predicate = check => check.Tags.Contains("ready"),ResponseWriter = WriteHealthCheckResponse
});// 健康检查响应写入器
async Task WriteHealthCheckResponse(HttpContext context, HealthReport report)
{context.Response.ContentType = "application/json";var result = JsonSerializer.Serialize(new{status = report.Status.ToString(),checks = report.Entries.Select(e => new{name = e.Key,status = e.Value.Status.ToString()})});await context.Response.WriteAsync(result);
}app.Run();

添加一个示例控制器

创建 Controllers/TestController.cs

using Microsoft.AspNetCore.Mvc;namespace HealthCheckDemo.Controllers;[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{private static int _requestCount = 0;[HttpGet]public IActionResult Get(){_requestCount++;// 每10个请求模拟一次故障if (_requestCount % 10 == 0){return StatusCode(500, "Simulated server error");}return Ok($"Request #{_requestCount}: Hello from TestController!");}
}

4. 测试健康检查

启动应用程序

dotnet run

测试不同健康检查端点

  1. 综合健康检查(所有检查):

    curl -k https://localhost:7003/health
    
  2. 存活检查(只检查应用本身):

    curl -k https://localhost:7003/health/live
    
  3. 就绪检查(检查应用和所有依赖):

    curl -k https://localhost:7003/health/ready
    

示例响应

成功响应

{"status": "Healthy","totalDuration": "00:00:00.1024567","checks": [{"name": "self","status": "Healthy","description": "Application is running","duration": "00:00:00.0000862"},{"name": "database","status": "Healthy","description": "Database connection is OK","duration": "00:00:00.1001234"},{"name": "redis","status": "Healthy","description": "Redis connection is OK","duration": "00:00:00.1002341"}]
}

失败响应

{"status": "Unhealthy","totalDuration": "00:00:00.2034567","checks": [{"name": "self","status": "Healthy","description": "Application is running","duration": "00:00:00.0000762"},{"name": "database","status": "Unhealthy","description": "Database connection failed","duration": "00:00:00.2001234"},{"name": "redis","status": "Healthy","description": "Redis connection is OK","duration": "00:00:00.2002341"}]
}

5. 与容器编排系统集成

创建 Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["HealthCheckDemo.csproj", "."]
RUN dotnet restore "HealthCheckDemo.csproj"
COPY . .
RUN dotnet build "HealthCheckDemo.csproj" -c Release -o /app/buildFROM build AS publish
RUN dotnet publish "HealthCheckDemo.csproj" -c Release -o /app/publishFROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "HealthCheckDemo.dll"]

Kubernetes 部署配置

创建 deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:name: healthcheck-demo
spec:replicas: 3selector:matchLabels:app: healthcheck-demotemplate:metadata:labels:app: healthcheck-demospec:containers:- name: healthcheck-demoimage: healthcheck-demo:latestports:- containerPort: 80# 存活探针 - 检查应用是否正在运行livenessProbe:httpGet:path: /health/liveport: 80initialDelaySeconds: 10periodSeconds: 10timeoutSeconds: 5failureThreshold: 3# 就绪探针 - 检查应用是否准备好接收流量readinessProbe:httpGet:path: /health/readyport: 80initialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 3failureThreshold: 1# 启动探针 - 检查应用是否已启动startupProbe:httpGet:path: /health/liveport: 80initialDelaySeconds: 10periodSeconds: 10failureThreshold: 30
---
apiVersion: v1
kind: Service
metadata:name: healthcheck-demo-service
spec:selector:app: healthcheck-demoports:- protocol: TCPport: 80targetPort: 80type: LoadBalancer

6. 高级功能:健康检查 UI

添加健康检查 UI

dotnet add package AspNetCore.HealthChecks.UI
dotnet add package AspNetCore.HealthChecks.UI.Client
dotnet add package AspNetCore.HealthChecks.UI.InMemory.Storage

更新 Program.cs

builder.Services.AddHealthChecks() 后添加:

// 添加健康检查 UI 服务
builder.Services.AddHealthChecksUI(setup =>
{setup.AddHealthCheckEndpoint("API", "/health");setup.SetEvaluationTimeInSeconds(60); // 每60秒检查一次setup.SetMinimumSecondsBetweenFailureNotifications(60); // 失败通知最小间隔
})
.AddInMemoryStorage();

在端点映射部分添加:

// 健康检查 UI 端点
app.MapHealthChecksUI(setup => 
{setup.UIPath = "/healthchecks-ui";setup.ApiPath = "/healthchecks-api";
});

现在您可以访问 /healthchecks-ui 查看健康检查的可视化界面。

7. 实际数据库健康检查

替换模拟的数据库检查为真实的 SQL Server 检查:

// 在 Program.cs 的顶部添加
using Microsoft.Data.SqlClient;// 替换模拟的数据库检查
.AddSqlServer(connectionString: builder.Configuration.GetConnectionString("DefaultConnection"),healthQuery: "SELECT 1;", // 简单的健康检查查询name: "sql",failureStatus: HealthStatus.Unhealthy,tags: new[] { "ready", "database" }
)

appsettings.json 中添加连接字符串:

{"ConnectionStrings": {"DefaultConnection": "Server=localhost;Database=master;User Id=sa;Password=YourPassword123;TrustServerCertificate=true;"},// 其他配置...
}

总结

通过这个完整的实例,您已经学会了:

  1. 健康检查的基本概念:存活检查、就绪检查和依赖检查
  2. 如何注册健康检查服务:使用 AddHealthChecks()AddCheck() 方法
  3. 如何创建自定义健康检查:实现简单的检查逻辑
  4. 如何配置健康检查端点:使用 MapHealthChecks() 方法
  5. 如何自定义响应格式:使用 ResponseWriter 选项
  6. 如何与容器编排系统集成:配置 Kubernetes 探针
  7. 如何添加健康检查 UI:使用健康检查 UI 包

健康检查是构建可靠、可观测的分布式系统的关键组件,它可以帮助您及时发现和解决问题,确保应用程序的高可用性。

http://www.dtcms.com/a/360186.html

相关文章:

  • 【MLLM】语音端到端大模型和Voice Agent发展
  • 【Java进阶】Java与SpringBoot线程池深度优化指南
  • GitHub 热榜项目 - 日榜(2025-08-31)
  • 【AI编程工具】使用Cursor快速搭建一套小型项目管理系统
  • mysql5.7.44安装遇到登录权限问题
  • 在Linux环境安装Maven(保姆级别)
  • macos调用chrome后台下载wasm-binaries.tar.xz
  • k8s---prometheus 监控
  • AI大模型实战解析-RAG知识库+LangChain项目实战
  • 《SVA断言系统学习之路》【01】即时断言概览
  • IDM(Internet Download Managerv 6.38)破除解版下载!IDM 下载器永久免费版!提升下载速度达5倍!安装及使用
  • 深入解析Linux系统中的/etc/hosts文件
  • 刷题日记0831
  • 盲孔轴旋转编码器轴设计与加工的几个注意事项
  • 网络爬虫是自动从互联网上采集数据的程序
  • 开源知识抽取框架 推荐
  • Python基础之元组列表集合字典
  • 数据化管理是什么意思?企业该如何进行数据化管理
  • 介绍GSPO:一种革命性的语言模型强化学习算法
  • 【系统分析师】高分论文:论信息系统的安全与保密设计
  • 利用爬虫获取淘宝商品信息,参数解析
  • 大语言模型(LLM)简介与应用分享
  • Linux 系统忘记 root 密码?紧急救援方案与原理详解
  • 【STM32】外部中断(下)
  • kkfile一键部署-ubuntu版
  • Transformer中的核心概念III-Attention
  • 江协示例3.1LED闪烁,下载程序后要复位LED才点亮的设置。
  • 随时随地开发:通过 FRP 搭建从 Ubuntu 到 Windows 的远程 Android 调试环境
  • leetcode_48 旋转图像
  • DAY50打卡