gRPC Gateway 支持健康检查。默认情况下,gRPC Gateway 会在 /healthz 路径上提供健康检查端点。
要启用健康检查,需要在 gRPC 的服务定义中添加一个 HealthCheck 服务:
syntax = "proto3";
import "google/api/annotations.proto";
import "google/api/field_behavior.proto";
import "google/protobuf/wrappers.proto";
package myservice;
service MyService {
rpc MyMethod (MyRequest) returns (MyResponse) {
option (google.api.http) = {
post: "/v1/my-method"
body: "*"
};
}
rpc AnotherMethod (AnotherRequest) returns (AnotherResponse) {
option (google.api.http) = {
post: "/v1/another-method"
body: "*"
};
}
// 添加 HealthCheck 定义
service HealthCheck {
rpc Check(google.protobuf.Empty) returns (google.protobuf.Empty);
}
}
然后,在 gRPC 的实现代码中,需要实现 HealthCheck 接口:
type server struct{}
// 实现 MyService 接口
func (*server) Check(ctx context.Context, in *emptypb.Empty) (*emptypb.Empty, error) {
return &emptypb.Empty{}, nil
}
func main() {
// 创建 gRPC Server 和 Gateway
srv := grpc.NewServer()
gwmux := runtime.NewServeMux()
// 将 MyService 注册到 gRPC Server 上
myservice.RegisterMyServiceServer(srv, &server{})
// 将 HTTP Handler 注册到 ServeMux 上
if err := myservice.RegisterMyServiceHandlerFromEndpoint(
context.Background(),
gwmux,
"localhost:8080",
[]grpc.DialOption{grpc.WithInsecure()},
); err != nil {
log.Fatalf("failed to register gateway: %v", err)
}
// 将 HealthCheck 注册到 gRPC Server 上
myservice.RegisterHealthCheckServer(srv, &server{})
go func() {
// 启动 gRPC Server
if err := srv.Serve(listener); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}()
go func() {
// 启动 HTTP Gateway
if err := http.ListenAndServe(":8080", gwmux); err != nil {
log.Fatalf("failed to serve gateway: %v", err)
}
}()
select {}
}
现在,当你访问 /healthz 路径时,gRPC Gateway 将会代理请求到 HealthCheck 接口,并返回 200 OK 响应。如果 HealthCheck 接口返回错误,则响应码将为 500 Internal Server Error。
你也可以通过自定义健康检查逻辑来实现自定义的健康检查端点。例如,在 server 的 Check 方法中添加一些业务逻辑,来判断服务是否健康:
func (*server) Check(ctx context.Context, in *emptypb.Empty) (*emptypb.Empty, error) {
if isHealthy() {
return &emptypb.Empty{}, nil
} else {
return nil, status.Error(codes.Internal, "service is not healthy")
}
}