gitee.com/h79/goutils@v1.22.10/rpc/health.go (about)

     1  package rpc
     2  
     3  import (
     4  	"context"
     5  	"gitee.com/h79/goutils/common/logger"
     6  	"google.golang.org/grpc"
     7  	"google.golang.org/grpc/health/grpc_health_v1"
     8  	"time"
     9  )
    10  
    11  type HealthClient struct {
    12  }
    13  
    14  func (client *HealthClient) Check(conn *grpc.ClientConn, service string, duration time.Duration) (int, error) {
    15  
    16  	c := grpc_health_v1.NewHealthClient(conn)
    17  	ctx, cancel := context.WithTimeout(context.Background(), time.Second*duration)
    18  	defer cancel()
    19  
    20  	in := grpc_health_v1.HealthCheckRequest{Service: service}
    21  
    22  	rsp, err := c.Check(ctx, &in)
    23  	if err != nil {
    24  		return int(grpc_health_v1.HealthCheckResponse_UNKNOWN), err
    25  	}
    26  	return int(rsp.Status), nil
    27  }
    28  
    29  func (client *HealthClient) Watch(conn *grpc.ClientConn, service string, duration time.Duration) (grpc_health_v1.Health_WatchClient, error) {
    30  
    31  	c := grpc_health_v1.NewHealthClient(conn)
    32  	ctx, cancel := context.WithTimeout(context.Background(), time.Second*duration)
    33  	defer cancel()
    34  
    35  	in := grpc_health_v1.HealthCheckRequest{Service: service}
    36  
    37  	rsp, err := c.Watch(ctx, &in)
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  	return rsp, nil
    42  }
    43  
    44  // HealthServer 健康检查实现
    45  type HealthServer struct{}
    46  
    47  // Check 实现健康检查接口,这里直接返回健康状态,这里也可以有更复杂的健康检查策略,比如根据服务器负载来返回
    48  func (h *HealthServer) Check(ctx context.Context, req *grpc_health_v1.HealthCheckRequest) (*grpc_health_v1.HealthCheckResponse, error) {
    49  	logger.Debug("RPC:Check, Service: %v", req.Service)
    50  	return &grpc_health_v1.HealthCheckResponse{
    51  		Status: grpc_health_v1.HealthCheckResponse_SERVING,
    52  	}, nil
    53  }
    54  
    55  // Watch
    56  // Performs a watch for the serving status of the requested service.
    57  // The server will immediately send back a message indicating the current
    58  // serving status.  It will then subsequently send a new message whenever
    59  // the service's serving status changes.
    60  //
    61  // If the requested service is unknown when the call is received, the
    62  // server will send a message setting the serving status to
    63  // SERVICE_UNKNOWN but will *not* terminate the call.  If at some
    64  // future point, the serving status of the service becomes known, the
    65  // server will send a new message with the service's serving status.
    66  //
    67  // If the call terminates with status UNIMPLEMENTED, then clients
    68  // should assume this method is not supported and should not retry the
    69  // call.  If the call terminates with any other status (including OK),
    70  // clients should retry the call with appropriate exponential backoff.
    71  func (h *HealthServer) Watch(req *grpc_health_v1.HealthCheckRequest, s grpc_health_v1.Health_WatchServer) error {
    72  	logger.Debug("RPC:Watch, Service: %v", req.Service)
    73  	if s != nil {
    74  		rsp := grpc_health_v1.HealthCheckResponse{Status: grpc_health_v1.HealthCheckResponse_SERVING}
    75  		return s.Send(&rsp)
    76  	}
    77  	return nil
    78  }
    79  
    80  func HealthCheck(grpcServer *grpc.Server) {
    81  	grpc_health_v1.RegisterHealthServer(grpcServer, &HealthServer{})
    82  }