在使用 Docker 部署 gRPC 服务时,可以使用以下两种方式实现健康检查:
- 使用 gRPC 健康检查协议
gRPC 提供了一个简单的健康检查协议,可以在服务端实现该协议,然后客户端通过调用该协议来检查服务是否可用。具体实现方法如下:
在服务端实现健康检查协议:
import (
"google.golang.org/grpc/health"
"google.golang.org/grpc/health/grpc_health_v1"
)
type server struct{}
func (s *server) Check(ctx context.Context, req *grpc_health_v1.HealthCheckRequest) (*grpc_health_v1.HealthCheckResponse, error) {
return &grpc_health_v1.HealthCheckResponse{
Status: grpc_health_v1.HealthCheckResponse_SERVING,
}, nil
}
func (s *server) Watch(req *grpc_health_v1.HealthCheckRequest, w grpc_health_v1.Health_WatchServer) error {
return status.Error(codes.Unimplemented, "Watch is not implemented")
}
在 Dockerfile 中暴露健康检查端口:
EXPOSE 50051
EXPOSE 8080
HEALTHCHECK --interval=5s --timeout=3s CMD grpc-health-probe -addr=:50051 -service=my_service_name || exit 1
其中,grpc-health-probe 是一个 gRPC 健康检查工具,可以通过执行以下命令安装:
go get github.com/grpc-ecosystem/grpc-health-probe
在 Kubernetes Deployment 中指定 livenessProbe:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-service
spec:
replicas: 3
selector:
matchLabels:
app: my-service
template:
metadata:
labels:
app: my-service
spec:
containers:
- name: my-service
image: my-service:latest
ports:
- name: grpc
containerPort: 50051
livenessProbe:
exec:
command:
- grpc_health_probe
- -addr=:50051
- -service=my_service_name
initialDelaySeconds: 5
periodSeconds: 5
- 自定义健康检查接口
如果不想使用 gRPC 健康检查协议,可以在服务端实现自定义的健康检查接口,然后通过 HTTP 接口来检查服务是否可用。具体实现方法如下:
在服务端实现自定义的健康检查接口:
import (
"net/http"
)
type server struct{}
func (s *server) handleHealthCheck(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}
func main() {
// ...
http.HandleFunc("/health", s.handleHealthCheck)
// ...
}
在 Dockerfile 中暴露健康检查端口并指定健康检查命令:
EXPOSE 50051
EXPOSE 8080
HEALTHCHECK --interval=5s --timeout=3s CMD curl --fail http://localhost:8080/health || exit 1
在 Kubernetes Deployment 中指定 livenessProbe:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-service
spec:
replicas: 3
selector:
matchLabels:
app: my-service
template:
metadata:
labels:
app: my-service
spec:
containers:
- name: my-service
image: my-service:latest
ports:
- name: grpc
containerPort: 50051
- name: http
containerPort: 8080
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 5
periodSeconds: 5