gRPC 其实已经对如何实现心跳和健康检查有了说明了,详情见 https://github.com/grpc/grpc/blob/master/doc/health-checking.md 。而且框架已现了基本的 API 且达到基本开箱即用的程度。

原则上来说,应该很简单,只是调用 API 而已。但是,实际上呢,即使努力百度和谷歌,我们还不一定能跑起来。

其中最关键的就是 如何定义心跳服务,如果你只是简单的看文档,会以为要实现一个 protobuf 服务呢。

实际上呢,并不是,我们只要定义一个独一无二的 服务名 即可(”” 空字符串 表示所有服务)。

type Server

  1. type Server struct {
  2. healthgrpc.UnimplementedHealthServer
  3. // contains filtered or unexported fields
  4. }
  5. func NewServer() *Server
  6. func (s *Server) Check(ctx context.Context, in *healthpb.HealthCheckRequest) (*healthpb.HealthCheckResponse, error)
  7. // 将需要检查的服务注册进map
  8. func (s *Server) SetServingStatus(service string, servingStatus healthpb.HealthCheckResponse_ServingStatus)
  9. func (s *Server) Watch(in *healthpb.HealthCheckRequest, stream healthgrpc.Health_WatchServer) error
  10. // Shutdown sets all serving status to NOT_SERVING
  11. func (s *Server) Shutdown()
  12. // Resume sets all serving status to SERVING
  13. func (s *Server) Resume()

使用

客户端

在grpc.WithDefaultServiceConfig 中配置 HealthCheckConfig同时还需要导入_ “google.golang.org/grpc/health”

  1. import _ "google.golang.org/grpc/health"
  2. conn, err := grpc.Dial(address,grpc.WithInsecure(),
  3. grpc.WithDefaultServiceConfig(
  4. fmt.Sprintf(`{"LoadBalancingPolicy": "%s",
  5. "HealthCheckConfig": {"ServiceName": "xxx"}}`
  6. , roundrobin.Name))
  7. )

一个完整客户端例子

  1. conn, err := grpc.DialContext(ctx,
  2. r.Scheme()+"://author/xxx",
  3. grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s",
  4. "MethodConfig": [{"Name": [{"Service": "%s"}],
  5. "RetryPolicy": {"MaxAttempts":2, "InitialBackoff": "0.1s", "MaxBackoff": "1s",
  6. "BackoffMultiplier": 2.0,
  7. "RetryableStatusCodes": ["UNAVAILABLE", "CANCELLED"]}}],
  8. "HealthCheckConfig": {"ServiceName": "%s"}}`, roundrobin.Name, *serv, "")),
  9. grpc.WithInsecure())

服务端

服务端注册一个叫xxxx的服务,用于grpc的健康检查。

  1. healthpb "google.golang.org/grpc/health/grpc_health_v1"
  2. s := grpc.NewServer()
  3. hs := health.NewServer()
  4. hs.SetServingStatus("",healthpb.HealthCheckResponse_SERVING)
  5. healthpb.RegisterHealthServer(s, hs)

注意:两个serverName要对应