go的alexliesenfeld/health介绍

 

alexliesenfeld/health GitHub 是 Go 生态里一个非常流行的健康检查库。

它主要解决:

 
服务是否健康?
依赖是否正常?
K8s readiness/liveness 怎么做?
 

比如:

  • MySQL 是否可用
  • Redis 是否连接成功
  • Kafka 是否正常
  • 下游 HTTP 服务是否正常
  • 当前服务是否 ready

它比简单的:

 
w.WriteHeader(200)
 

强大很多。


一、health 是干什么的

核心作用:

 
提供标准化健康检查 endpoint
 

例如:

 
/health
/ready
/live
 

适用于:

  • Kubernetes
  • Docker
  • Prometheus
  • Nginx
  • 云原生微服务

二、为什么需要 health check

很多人一开始:

 
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok"))
})
 

但这有个巨大问题:

 
服务进程活着 ≠ 服务可用
 

例如:

  • 数据库挂了
  • Redis 挂了
  • Kafka 不通
  • 下游 API 超时

进程还活着,但业务已经不可用了。

所以现代服务通常需要:

类型作用
liveness 进程是否活着
readiness 是否可接流量
startup 是否启动完成

三、安装

 
go get github.com/alexliesenfeld/health
 

四、最简单例子


示例

 
package main

import (
"context"
"fmt"
"github.com/alexliesenfeld/health"
"log"
"net/http"
)

func main() {

checker := health.NewChecker(

health.WithCheck(health.Check{
Name: "app",

Check: func(ctx context.Context) error {
return nil
},
}),
)

http.Handle("/health", health.NewHandler(checker))

log.Fatal(http.ListenAndServe(":8080", nil))
}
 

访问:

 
GET /health
 

返回:

 
{
"status": "up",
"details": {
"app": {
"status": "up"
}
}
}
 

五、核心概念

最重要:

 
health.Check
 

一个 Check

代表:

 
一个组件的健康状态
 

例如:

  • mysql
  • redis
  • kafka
  • elasticsearch

结构

 
health.Check{
Name: "mysql",

Check: func(ctx context.Context) error {
return db.PingContext(ctx)
},
}
 

规则:

  • return nil
    → healthy
  • return error
    → unhealthy

六、数据库检查(最常用)


MySQL

 
health.WithCheck(health.Check{
Name: "mysql",

Check: func(ctx context.Context) error {
return db.PingContext(ctx)
},
})
 

Redis

 
health.WithCheck(health.Check{
Name: "redis",

Check: func(ctx context.Context) error {
return rdb.Ping(ctx).Err()
},
})
 

七、返回结果

如果 Redis 挂了:

 
{
"status": "down",
"details": {
"mysql": {
"status": "up"
},
"redis": {
"status": "down",
"error": "connection refused"
}
}
}
 

HTTP 状态:

 
503 Service Unavailable
 

这个非常适合:

  • K8s readinessProbe
  • ELB 健康检查
  • Prometheus blackbox

八、同步检查 vs 异步检查(重点)

这是这个库最大的特点。


1. WithCheck(同步)

 
health.WithCheck(...)
 

每次 HTTP 请求:

 
都会重新执行检查
 

例如:

 
/health
-> ping mysql
-> ping redis
-> 返回
 

优点:

  • 数据实时

缺点:

  • 容易雪崩
  • 高并发可能打挂依赖

2. WithPeriodicCheck(异步)

这是生产环境推荐方式。


示例

 
health.WithPeriodicCheck(
10*time.Second,
1*time.Second,

health.Check{
Name: "mysql",

Check: func(ctx context.Context) error {
return db.PingContext(ctx)
},
},
)
 

意思:

 
后台每 10 秒检查一次
 

HTTP 请求:

 
直接读缓存
 

因此:

  • 响应极快
  • 不会压垮 DB
  • 更适合 K8s

九、缓存机制

默认:

 
1 秒缓存
 
 
health.WithCacheDuration(time.Second)
 

可以关闭:

 
health.WithDisabledCache()
 

十、超时控制(很重要)


全局超时

 
health.WithTimeout(5 * time.Second)
 

单个检查超时

 
health.Check{
Name: "mysql",

Timeout: 2 * time.Second,
}
 

内部其实用的就是:

 
context.WithTimeout
 

十一、Kubernetes 中的典型用法


readinessProbe

 
readinessProbe:
httpGet:
path: /health
port: 8080
 

如果:

  • mysql down
  • redis down

health 返回:

 
503
 

K8s 就不会再给 Pod 分流量。


livenessProbe

通常:

 
不要检查外部依赖
 

否则:

 
数据库挂了
→ K8s 重启所有 Pod
→ 雪崩
 

这是非常经典的生产事故。


十二、生产最佳实践(很重要)


1. liveness 不检查依赖

只检查:

  • 进程是否卡死
  • goroutine 是否正常

2. readiness 才检查依赖

例如:

  • mysql
  • redis
  • kafka

3. 异步检查优于同步检查

推荐:

 
WithPeriodicCheck
 

不要:

 
每次请求都 ping mysql
 

4. health endpoint 必须非常快

K8s 会频繁调用:

 
每几秒一次
 

十三、完整生产级示例


Gin + MySQL + Redis

 
package main

import (
"context"
"database/sql"
"github.com/alexliesenfeld/health"
"github.com/gin-gonic/gin"
"github.com/redis/go-redis/v9"
"time"
)

func main() {

var db *sql.DB
var rdb *redis.Client

checker := health.NewChecker(

health.WithTimeout(3*time.Second),

health.WithPeriodicCheck(
10*time.Second,
1*time.Second,

health.Check{
Name: "mysql",

Check: func(ctx context.Context) error {
return db.PingContext(ctx)
},
},
),

health.WithPeriodicCheck(
10*time.Second,
1*time.Second,

health.Check{
Name: "redis",

Check: func(ctx context.Context) error {
return rdb.Ping(ctx).Err()
},
},
),
)

r := gin.Default()

r.GET("/health", gin.WrapH(
health.NewHandler(checker),
))

r.Run(":8080")
}
 

十四、这个库为什么受欢迎

因为它设计非常 Go 风格:


1. 函数式 Option

 
health.NewChecker(
health.WithTimeout(...),
health.WithCheck(...),
)
 

很 idiomatic Go。


2. context 支持很好

所有 check:

 
func(ctx context.Context) error
 

天然支持:

  • timeout
  • cancel

3. 可扩展性很好

支持:

  • middleware
  • interceptor
  • listener

十五、状态监听(高级)

状态变化时通知:

 
health.WithStatusListener(
func(ctx context.Context, state health.CheckerState) {
log.Println(state.Status)
},
)
 

可以:

  • 发告警
  • 打日志
  • Prometheus metrics

十六、一些争议(非常重要)

社区一直有争论:

 
health check 到底该不该检查依赖?
 

Reddit 上讨论很多。


反对派观点

例如:

 
mysql 挂了
→ 所有服务 health down
→ K8s 全部摘流
→ 整个系统崩
 

形成:

 
级联故障
 

推荐实践

通常:

类型建议
liveness 不检查外部依赖
readiness 检查关键依赖

这是目前最主流方案。


十七、和其它库对比

特点
alexliesenfeld/health 现代、灵活、功能全
heptiolabs/healthcheck 老牌
go-health 偏复杂
gin-healthcheck 太轻量

目前:

alexliesenfeld/health 官方仓库 算 Go 云原生领域里比较现代的一套方案。 

 
 
 
 
posted @ 2026-05-27 11:30  苦逼yw  阅读(7)  评论(0)    收藏  举报