Go应用健康探针需区分/livez(检查进程是否卡死,不依赖外部服务)和/readyz(检查依赖就绪状态,超时≤1s),用net/http几行代码即可实现;部署时需确保探针超时小于periodSeconds、failureThreshold设为3–5、路径端口匹配且/livez避免写操作。

在 Go 应用中实现健康探针(Health Probe),核心是暴露一个轻量、快速响应的 HTTP 端点,供 Kubernetes 或其他编排系统定期调用,以判断容器是否就绪(/readyz)或存活(/livez)。它不需复杂逻辑,但必须稳定、低延迟、不依赖外部故障点(如数据库连接失败不应直接导致 /livez 失败)。
区分 /livez 和 /readyz 的语义
Kubernetes 使用两个独立探针:liveness 探针失败会重启容器;readiness 探针失败则从服务端点中移除该实例。Go 服务中应明确分离二者职责:
- /livez:只检查进程自身是否卡死(如 goroutine 泄漏、死锁)、关键内部状态(如主事件循环是否运行)。避免访问数据库、Redis、下游 HTTP 服务等。
- /readyz:可检查依赖服务是否就绪(如 DB 连接池可用、配置已加载、缓存预热完成),但超时要严格(建议 ≤1s),失败仅影响流量接入,不触发重启。
用标准 net/http 实现基础健康端点
无需额外框架,几行代码即可启动可靠探针:
http.HandleFunc("/livez", func(w http.ResponseWriter, r *http.Request) {
// 检查基本运行状态(例如:主 goroutine 是否存活)
select {
case <-time.After(10 * time.Millisecond):
w.WriteHeader(http.StatusOK)
w.Write([]byte("ok"))
default:
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("deadlock suspected"))
}
})
http.HandleFunc("/readyz", func(w http.ResponseWriter, r http.Request) {
// 示例:检查数据库连接(带超时)
ctx, cancel := context.WithTimeout(r.Context(), 500time.Millisecond)
defer cancel()
if err := db.PingContext(ctx); err != nil {
http.Error(w, "db unreachable", http.StatusServiceUnavailable)
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("ready"))
})
使用第三方库简化管理(如 go-health)
当依赖项较多时,github.com/InVisionApp/go-health 提供了声明式注册和自动聚合能力:
立即学习“go语言免费学习笔记(深入)”;
- 定义多个检查器(DB、Redis、HTTP 外部服务、自定义逻辑)
- 支持并行执行、超时控制、失败阈值
- 自动返回结构化 JSON(含各检查项状态、耗时、错误详情)
- 内置
/health/live和/health/ready路由,与 Kubernetes 探针无缝对接
示例片段:
h := health.New()
h.AddReadinessCheck("db", health.CheckerFunc(func() error {
return db.Ping()
}))
h.AddLivenessCheck("goroutines", health.CheckerFunc(func() error {
if runtime.NumGoroutine() > 1000 {
return errors.New("too many goroutines")
}
return nil
}))
http.Handle("/health/live", h.LiveHandler())
http.Handle("/health/ready", h.ReadyHandler())
部署时的关键注意事项
探针在生产中失效常因配置不当而非代码问题:










