微服务健康检查需区分/health(存活)和/ready(就绪)路径,前者轻量检测进程状态,后者带超时并发检查全量依赖并返回503;K8s探针须严格对应路径,避免无超时、缓存、错误码混用等坑。

/health(存活)、/ready(就绪)两类探针。
为什么不能只用 http.StatusOK 简单返回 "OK"
单纯返回 200 + "OK" 只能说明进程没挂,但微服务真实可用性取决于依赖:数据库连不上、Redis 超时、下游 API 返回 503,服务其实已不可用。Kubernetes 的 readinessProbe 若仍把流量导过来,会导致请求堆积、雪崩。生产环境必须把依赖状态显式聚合进响应。
- 依赖检测必须设超时(如
context.WithTimeout),避免卡住探针 - 数据库
PingContext、RedisPing(ctx).Result()都要带上下文,不能用无超时的Ping() -
/health建议轻量(仅进程+基础依赖),/ready才做全量依赖检查
如何用 net/http 实现可组合的依赖检查器
硬编码一堆 if db.Ping() != nil 很难维护。推荐用函数类型 Checker 抽象每个依赖的探测逻辑,便于复用、测试和开关:
type Checker func() (string, error)
func DBChecker(db *sql.DB) Checker {
return func() (string, error) {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
if err := db.PingContext(ctx); err != nil {
return "database", fmt.Errorf("ping failed: %w", err)
}
return "database", nil
}
}
func RedisChecker(client *redis.Client) Checker {
return func() (string, error) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
if _, err := client.Ping(ctx).Result(); err != nil {
return "redis", fmt.Errorf("ping failed: %w", err)
}
return "redis", nil
}
}
这样,/ready 处理器只需遍历 map[string]Checker 并并发执行,既清晰又可控。
Kubernetes 探针配置与路径分工必须匹配
Go 服务暴露了 /health 和 /ready,但若 K8s 的 livenessProbe 和 readinessProbe 都指向同一个路径,就失去了语义分离的意义。
第一步】:将安装包中所有的文件夹和文件用ftp工具以二进制方式上传至服务器空间;(如果您不知如何设置ftp工具的二进制方式,可以查看:(http://www.shopex.cn/support/qa/setup.help.717.html)【第二步】:在浏览器中输入 http://您的商店域名/install 进行安装界面进行安装即可。【第二步】:登录后台,工具箱里恢复数据管理后台是url/sho
立即学习“go语言免费学习笔记(深入)”;
-
livenessProbe应调用/health:只检查进程存活、内存泄漏、goroutine 泄漏等,不查外部依赖(避免误杀) -
readinessProbe必须调用/ready:包含 DB、Redis、关键下游等全量依赖,任一失败即返回 503,K8s 立刻摘流量 -
startupProbe可复用/ready,但failureThreshold和periodSeconds要放宽(如 30s 检查一次,连续 5 次失败才重启)
YAML 示例片段:
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
常见踩坑:超时、缓存、错误码混用
健康检查接口看似简单,但线上最常出问题的恰恰是细节:
-
不设超时:DB 或 Redis 响应慢,整个
/ready卡住 30 秒,K8s 连续失败直接重启服务 - 缓存结果:用全局变量缓存上一次检查结果?错。健康检查必须实时反映当前状态,否则故障发生后探针仍报 “up”
-
错误码乱用:依赖失败返回
http.StatusInternalServerError(500)?不对。应返回http.StatusServiceUnavailable(503),这是 K8s readiness 的标准失败信号 -
日志轰炸:每秒被探针调用 5 次,每次都在日志里打 “DB OK”,刷爆日志。健康检查日志建议
level=debug或完全关闭









