服务上k8s之後, 除了介接的系统会来打API之外, 在API没有被触发的期间如果服务发生问题, 很难被事先发现。
以我们现行的专案来说, k8s上面起的服务有50-60个, 每个服务还有多个pod, 况且每个服务的使用频率不一样, 有的每秒会被打几百次, 发生问题很快就能被发现, 有的一两个月都不会被打到一次, 等到要用的时候才发现它坏掉, 那就是一阵手忙脚乱了。
所以提供一个health check
让k8s可以帮忙关怀各个服务的状况, 确实掌握丛集中里面大大小小, 从热门到边缘的服务状况, 主动发现问题才能在问题引爆之前多争取一点时间。
这边采用的方式是在服务上开启一个http port, 让k8s定期发送一个 HTTP request给Pod。
cmd.go 加上启动 http port function runHealth()
, 在每次k8s询问的时候打一次自身的Ping并回应服务执行时长。
grpcServer := runGrpcServer(shutdownObserver, sv)
// health check
go runHealth()
........ (省略)
func runHealth() {
started := time.Now()
connSelf, err := grpc.Dial("localhost"+config.Listen, grpc.WithInsecure())
if err != nil {
Logger.WithFields(map[string]interface{}{"error": err}).Errorf("连线失败")
}
coco := coconut.NewCoconutClient(connSelf)
Logger.Debugf("Healthy API is Running at port: %s", config.HealthPort)
http.HandleFunc(config.HealthPath, func(w http.ResponseWriter, r *http.Request) {
// 确认gRPC服务有通
ping, err := coco.Ping(context.Background(), &coconut.PingRequest{})
if err == nil {
w.WriteHeader(200)
data := fmt.Sprintf("Already run: %v", time.Since(started))
if _, errw := w.Write([]byte(data)); errw != nil {
Logger.WithFields(map[string]interface{}{"error": errw}).Errorf("runHealth")
}
} else {
w.WriteHeader(500)
Logger.Errorf("Service Not Ready yet, ping: %#v, err: %s", ping, err.Error())
}
})
logrus.Fatal(http.ListenAndServe(":"+config.HealthPort, nil))
}
在去年的k8s主题中有学到 kubelet 可以执行三种探测
health check 这里采用的是 readinessProbe
, 主要用来判断Pod是否可以接收request。所以会在部署k8s deployment.yaml时加上这段
template:
spec:
containers:
readinessProbe:
httpGet:
path: {{ health.Path }}
port: {{ health.httpPort }}
initialDelaySeconds: 2
periodSeconds: 5
参考资料
<<: Proxmox VE 虚拟机 Cloud-Init 应用
>>: Flutter体验 Day 19-InheritedWidget
摘要 交叉验证不同方法组合的模型准确率 1.1 参数说明 1.2 程序码 选择模型组合方法 2.1 ...
Virtual Judge ZeroJudge 题意 输入一整数,输出是否为质数或 Emirp 需...
1.前言 今天主要介绍我们後续系列案例所会使用到的ST01扩充板,在开始前稍微说明这篇可能比较偏工商...
Achieving low average tested error isn't good eno...
Recyclerview Recyclerview在App开发中十分常见,接下来就用kotlin来呈...