C# 健康检查实现方法 C# ASP.NET Core如何添加健康检查

来源:这里教程网 时间:2026-02-21 17:42:01 作者:

HealthCheckService 和 IHealthChecksBuilder 怎么用

ASP.NET Core 的健康检查不是靠手动轮询或写个

GET /health
就完事的,它依赖内置的
HealthCheckService
后台服务和
IHealthChecksBuilder
注册机制。你得先在
Program.cs
里调用
AddHealthChecks()
,它返回的就是
IHealthChecksBuilder
实例,所有检查项都通过它添加。

常见错误是直接 new 一个自定义类然后塞进 DI 容器,结果健康端点返回始终是

Healthy
或直接 500——因为没走健康检查管道,
HealthCheckService
根本不知道它存在。

必须用
services.AddHealthChecks().AddCheck<mydbhealthcheck>("db")</mydbhealthcheck>
,不能只注册
MyDbHealthCheck
类型
自定义检查类必须实现
IHealthCheck
接口,且
CheckHealthAsync
方法不能抛未捕获异常(会转成
Unhealthy
,但堆栈不返回给客户端)
如果检查逻辑含异步 IO(如数据库连接测试),必须用
await
,别用
.Result
.Wait()
,否则可能死锁

如何添加 HTTP 端点并控制响应格式

注册完检查项后,还得暴露一个可访问的 endpoint,靠的是

MapHealthChecks
扩展方法。它默认返回 JSON,但字段精简(只有
status
results
),不包含耗时、异常详情等调试信息。

开发阶段常需要看到每个检查项的执行时间或失败原因,这时得启用

ResponseWriter
自定义输出逻辑,而不是改用第三方中间件拦截响应体。

app.MapHealthChecks("/health", new HealthCheckOptions { ResponseWriter = WriteDetailedHealthResponse })
WriteDetailedHealthResponse
是个委托,接收
HttpContext
HealthReport
,可序列化
report.Entries
中每个
HealthReportEntry
Exception
Duration
属性
生产环境禁用详细输出,避免泄露内部信息;可用
Environment.IsDevelopment()
控制开关

数据库连接健康检查为什么总是 Healthy 即使连不上

AddSqlServer
AddNpgsql
等扩展方法时,默认只检查连接字符串能否解析,不真连数据库。这是为了性能——健康检查端点不该成为 DB 连接风暴源头。

真正验证连通性,得传入

configureOptions
参数,开启
includeEntityFramework
或显式调用
Open()
+
Close()

SQL Server:
.AddSqlServer(connectionString, healthQuery: "SELECT 1", name: "sql")
——
healthQuery
是关键,不设就只是解析连接字符串
EF Core 场景下,若用了
AddDbContextHealthCheck<appdbcontext></appdbcontext>
,它默认会调用
context.Database.CanConnectAsync()
,但前提是上下文已正确注册且无作用域问题
注意连接超时:健康检查默认超时 30 秒,可通过
timeout
参数缩短,比如
timeout: TimeSpan.FromSeconds(5)

多个健康检查并发执行时状态怎么聚合

默认策略是「任意一项 Unhealthy → 整体 Unhealthy」,由

HealthReport.Status
的计算逻辑决定。这个聚合行为不可配置,但你可以用
RequireHealthy
RequireHealthyExcept
分组控制依赖关系。

比如缓存服务挂了不影响主流程,但数据库挂了必须告警,这时就得拆成两个 endpoint,而不是塞进同一个检查组。

AddCheck
注册的每一项独立执行,彼此不阻塞;
HealthCheckService
并发运行它们(非顺序)
想让某些检查仅在其他检查 Healthy 时才运行?不行——框架不支持条件触发,需在
CheckHealthAsync
内部手动判断并返回
HealthCheckResult.Degraded()
或跳过逻辑
聚合结果中的
HealthReport.TotalDuration
是所有检查最大耗时,不是总和;单个检查若超时,会被取消并标记为
Unhealthy

最易忽略的一点:健康检查中间件在请求管道的位置。它必须放在

UseRouting
之后、
UseEndpoints
之前,否则
MapHealthChecks
不生效。顺序错,/health 就 404。

相关推荐