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.pswp.cn/diannao/97782.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/97782.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/97782.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java生产级避坑指南】8. Tomcat线程池下的内存地雷:ThreadLocal泄漏检测与实战解决

摘要:某金融交易系统(Spring Boot 2.7 + Tomcat 9)在线上运行时出现严重内存泄漏:堆内存(4GB)72小时内耗尽并触发OOM,日均200万请求场景下,Full GC频率从正常1次/天飙升至6次/小时。排查发现,根源是ThreadLocal未清理——Tomcat线程池复用线程时,UserInfo等大对象被T…

云端职达:你的AI求职专属猎头,颠覆传统招聘模式

在求职的“金三银四”或“金九银十”,每一分每一秒都弥足珍贵。面对浩如烟海的招聘信息,你是否还在花费大量时间一条条筛选、重复投递简历,最终却常常石沉大海?传统求职方式的低效和“已读不回”的窘境,让许多求职者感…

Parasoft C/C++test如何实现开发环境内嵌的安全检测

Parasoft 作为嵌入式质量与安全领域的全球领先供应商,其 C/Ctest 平台依托 IDE 级原生集成、实时合规检测引擎与缺陷闭环治理框架,将传统静态应用安全测试由项目末期集中执行前移至编码阶段,显著降低缺陷修复成本并缩短认证周期,为…

leetcode-每日一题-人员站位的方案数-C语言

3025. 人员站位的方案数 I 输入&#xff1a; 2 < n < 50 points[i].length 2 0 < points[i][0], points[i][1] < 50 points[i] 点对两两不同。 // 按x降序&#xff0c;按y升序 int cmp(const void *a, const void *b) {int *p *(int **)a;int *q *(int **)b;if(…

ClickHouse中的ON CLUSTER关键字

目录 ClickHouse中的ON CLUSTER关键字 前置基础 ClickHouse 中的 MergeTree 与 ReplicatedMergeTree ON CLUSTER 查询在集群上的正确用法(为什么 查询/写入数据 不用 ON CLUSTER) 与不使用 ON CLUSTER 的区别 注意事项与坑 常用配套命令 ClickHouse中的ON CLUSTER关键字 前置…

Python绘图动态可视化:实时音频流

在数据可视化中&#xff0c;动画是一种非常有效的方式&#xff0c;可以帮助我们更好地理解数据的变化和动态过程。Python 的 matplotlib.animation 模块提供了强大的功能来创建动画。本文将介绍如何使用 matplotlib.animation 创建简单的动画&#xff0c;并展示一个更复杂的实时…

【Vue2 ✨】Vue2 入门之旅(七):事件处理

在前几篇文章中&#xff0c;我们学习了指令与过滤器。本篇将介绍 事件处理&#xff0c;重点包括 v-on、事件修饰符以及键盘事件。 目录 事件绑定 v-on事件修饰符键盘事件小结 事件绑定 v-on Vue 使用 v-on&#xff08;缩写 &#xff09;来监听事件。 <div id"app&qu…

高效数据传输的秘密武器:Protobuf

当涉及到网络通信和数据存储时&#xff0c;数据序列化一直都是一个重要的话题&#xff1b;特别是现在很多公司都在推行微服务&#xff0c;数据序列化更是重中之重&#xff0c;通常会选择使用 JSON 作为数据交换格式&#xff0c;且 JSON 已经成为业界的主流。但是 Google 这么大…

腾讯混元翻译大模型Hunyuan-MT-7B:重塑跨语言沟通的技术革命

腾讯混元翻译大模型Hunyuan-MT-7B&#xff1a;重塑跨语言沟通的技术革命 腾讯混元Hunyuan-MT-7B大模型的发布标志着机器翻译领域进入全新时代&#xff0c;本文将深入解析这一突破性技术如何实现30种语言翻译冠军的卓越表现 一、Hunyuan-MT-7B核心架构解析 1.1 基于Transformer的…

End-To-End 之于推荐-kuaishou OneRec2 笔记

End_To_End 之于推荐onerec里&#xff0c;快手利用大模型做了推荐架构的革命&#xff0c;几个月后&#xff0c;v2之于v1是一些技术细节进行了进一步迭代&#xff0c;主要是以下两个方面&#xff1a; 1. 架构层面的突破&#xff1a;Lazy Decoder-Only 背景问题&#xff1a;V1 的…

【LeetCode】3670. 没有公共位的整数最大乘积 (SOSDP)

3670. 没有公共位的整数最大乘积 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 思路&#xff1a; SOSDP 本题我们显然不能枚举每一个数对&#xff0c;n 的复杂度显然超时&#xff0c;所以考虑优化 我们考虑一个二进制数 mask&#xff0c;因为我们必须要选没有任…

Sping Web MVC入门

1.什么是Sping Web MVC1.1MVC定义2.什么是Spring MVC

LLM面试50问:NLP/RAG/部署/对齐/安全/多模态全覆盖

太好了!下面按你点名的 6 大主题(NLP、检索/RAG、部署、对齐、 安全、多模态)给出深度版答案 + 关键公式/推导 + 最小可跑示例代码 + 常见坑。都尽量精炼到“拿来即用/面试可白板推导”的粒度。 NLP(架构、位置编码、指令跟随) 1) RoPE 长上下文与缩放 要点:RoPE 将位置…

计算机网络技术(四)完结

七&#xff0c;虚拟局域网VLAN1&#xff0c;VLAN概述通过设置虚拟局域网来实现&#xff0c;pc之间实现快速安全通信。对比说明&#xff1a;之前交换机的广播来实现通信&#xff0c;但同意也带来了几个问题&#xff0c;过大的广播域&#xff0c;造成了带宽的浪费&#xff0c;过大…

VibeVoice 部署全指南:Windows 下的挑战与完整解决方案

VibeVoice 部署全指南&#xff1a;Windows 下的挑战与完整解决方案 目标读者&#xff1a;希望在本地部署 VibeVoice 进行文字转语音&#xff08;TTS&#xff09;的开发者、研究人员或爱好者 关键词&#xff1a;VibeVoice、FlashAttention-2、Windows 部署、CUDA 加速、FFmpeg、…

一次别开生面的Java面试

场景描述&#xff1a; 在一家知名互联网大厂的面试室中&#xff0c;谢飞机&#xff0c;一个自信满满的程序员&#xff0c;正在经历一场别开生面的Java面试。面试官以严肃的态度开始了这场技术问答。第一轮&#xff1a;基础知识问答 面试官&#xff1a;"我们先从简单的开始…

web自动化测试(selenium)

目录 测试前的准备 驱动 安装驱动管理 selenium库 使用selenium编写代码 自动化测试常用函数 元素的定位 cssSelector xpath 查找元素 点击/提交对象 模拟按键输入 清除文本内容 获取文本信息 获取当前页面标题和URL 窗口 切换窗口 窗口设置大小 屏幕截图 …

民间药方偏方网站整站源码 带数据PHP版

内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示三、学习资料下载一、详细介绍 民间药方偏方网站整站源码 带数据PHP版 这是一个聚焦中国民间药方的平台。平台设有搜索功能&#xff0c;方便用户查找药方&#xff0c;还对药方进行了内科、外科、肿瘤等多类分类&#x…

C++ 条件变量,互斥锁

C 中多线程编程的两个核心同步原语&#xff1a;互斥锁 (Mutex) 和 条件变量 (Condition Variable)。它们是实现线程间安全通信和协调的关键。1. 互斥锁 (Mutex)核心概念互斥锁用于保护共享数据&#xff0c;确保同一时间只有一个线程可以访问该数据&#xff0c;从而避免数据竞争…

MySQL 8.0 窗口函数详解:让数据分析更简单高效

在日常的数据分析工作中&#xff0c;我们经常需要对数据进行分组排序、计算移动平均值、统计累计求和等操作。在MySQL 8.0之前&#xff0c;这类需求通常需要编写复杂的子查询或连接查询才能实现。而MySQL 8.0引入的窗口函数&#xff08;Window Functions&#xff09;极大地简化…