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 云原生领域里比较现代的一套方案。

浙公网安备 33010602011771号