C# gRPC健康检查方法 C#如何为gRPC服务实现健康检查

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

gRPC健康检查用哪个接口

必须实现

Health.HealthBase
,这是 gRPC 官方健康检查协议定义的服务基类。它不是自定义接口,不能随便起名或改方法签名——否则客户端(比如
grpc_health_probe
或 Envoy)根本识别不了。

生成服务代码时,需确保 proto 文件是官方的

health.proto
(来自 grpc/grpc),且引用的是
Grpc.Health.Checking
NuGet 包(.NET 6+ 推荐)或
Grpc.AspNetCore.HealthChecks
(旧版兼容用)。

如何注册 HealthService 到 ASP.NET Core Host

Program.cs
中,不能只 AddGrpc() 就完事;健康检查服务需要显式注册并启用中间件。

调用
services.AddGrpcHealthChecks()
注册服务端逻辑
调用
app.MapGrpcHealthChecks("/healthz")
暴露端点(路径可自定义,但必须是 gRPC endpoint,不是 HTTP GET)
如果同时跑 HTTP 和 gRPC,确保 Kestrel 配置支持 HTTP/2(尤其开发时启用 TLS 或用
http://localhost:5001
+
"Http2UnencryptedSupport": true

注意:

MapGrpcHealthChecks
注册的是一个独立的 gRPC 服务,和你的业务 service 无关,它响应的是
HealthCheckRequest
并返回
HealthCheckResponse

如何动态控制某个服务的健康状态

默认所有服务都返回

SERVING
,但实际中常需根据依赖(DB、Redis、下游 gRPC)状态切换。得靠
IHealthCheckService
实例手动更新。

注入
IHealthCheckService
(由
AddGrpcHealthChecks()
提供)
healthCheckService.SetStatus("your-service-name", HealthStatus.NotServing)
主动设为不健康
服务名必须和你在
Check
请求里传入的
service
字段一致;空字符串对应整体状态
别在请求处理中频繁调用
SetStatus
——它不是线程安全的写操作,建议配合后台轮询 + 状态缓存(如
ConcurrentDictionary

示例:DB 连接失败时,执行

healthCheckService.SetStatus("user-service", HealthStatus.NotServing)
,之后客户端查
Check(service: "user-service")
就会收到
NOT_SERVING

常见连不通问题:客户端报 “UNAVAILABLE” 或 “failed to connect to all addresses”

这不是健康检查逻辑错了,而是底层连接失败。优先排查:

grpc_health_probe
是否用了
-tls-server-name
(启用了 TLS 时必须指定)
Kestrel 是否监听了 HTTP/2 端口(
http/1.1
协议无法承载 gRPC 健康检查)
防火墙或 Istio/Envoy 是否拦截了非
/
路径的 gRPC 流量(
/healthz
是合法路径,但某些代理默认只放行
/
客户端是否用对了 scheme:
dns:///localhost:5001
(非 TLS)或
dns:///localhost:5001
+
--tls
(TLS)

真正容易被忽略的是:健康检查服务本身不参与你的业务 service 的生命周期管理——哪怕你关掉所有业务 service,

/healthz
仍可能返回
SERVING
,除非你显式调用
SetStatus
修改。

相关推荐