在 Kubernetes 中,健康检查(Probe) 是保障服务稳定运行的核心能力之一,它能帮助我们更智能地管理应用的生命周期和流量分发。
但在实际生产环境中,Readiness 和 Liveness 这两种探针经常被混用或误用。配置不当轻则导致服务流量抖动,影响用户体验;重则可能引发 Pod 频繁重启,甚至产生服务雪崩的连锁反应。
本文将系统性地解析两者的设计目的、工作机制与核心差异,提供清晰的配置示例与最佳实践,并结合 Spring Boot 应用给出从开发到部署的完整方案。
1、为什么需要 Readiness 和 Liveness 探针?
在没有配置健康检查探针时,Kubernetes 只能感知到一些基础状态:Pod 是否被成功调度、容器进程是否在运行。
然而,这远远不足以判断一个应用是否真正“健康”并准备好提供服务,我们常会遇到以下棘手场景:
- 应用启动缓慢:例如一个庞大的 Spring Boot 应用,容器状态虽已显示为
Running,但内部的服务、连接池可能仍在初始化。
- 应用内部卡死:程序可能因死循环、线程死锁或某些阻塞操作而失去响应,但容器进程并未退出。
- 外部依赖异常:应用所依赖的数据库、Redis 或消息队列暂时不可用,此时若继续接收用户流量,只会返回错误。
Readiness(就绪探针)与 Liveness(存活探针)正是为了精准解决上述问题而设计的两种机制。
2、Readiness Probe:流量守卫者
2.1 核心作用
判断 Pod 是否已经“就绪”,可以安全地接收来自 Service 的流量。
- ❌ 检查失败:Kubernetes 会将此 Pod 从关联的 Service 的 Endpoints 列表中移除。后续的请求将不会被负载均衡到该 Pod。
- ✅ 检查成功:Pod 会被重新加入 Service 的 Endpoints,开始接收流量。
- ⚠️ 重要特性:Readiness Probe 失败不会导致容器重启。
2.2 典型使用场景
- 应用启动阶段:等待 Spring Boot 完成上下文初始化、数据源连接建立。
- 依赖服务异常:当数据库、Redis 或消息中间件连接失败时。
- 服务自保护状态:当服务触发熔断、限流或主动降级时,应暂时拒绝新流量。
- 优雅下线流程:配合
lifecycle.preStop 钩子,实现平滑终止。
2.3 示例配置(HTTP 探针)
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 10 # 容器启动后等待10秒开始第一次探测
periodSeconds: 5 # 每5秒执行一次探测
timeoutSeconds: 2 # 探测请求超时时间为2秒
failureThreshold: 3 # 连续失败3次才标记为不健康
2.4 Spring Boot Readiness 实现示例
在 Spring Boot 应用中,我们可以自定义健康指示器来精确控制就绪状态。
@Component
public class ReadinessHealthIndicator implements HealthIndicator {
@Override
public Health health() {
if (dbAvailable() && cacheAvailable()) {
return Health.up().build();
}
return Health.down()
.withDetail("reason", "dependency unavailable")
.build();
}
}
逻辑说明:
- 当核心依赖(如数据库、缓存)不可用时,探针返回
DOWN,Pod 会被移出流量池。
- 应用进程本身保持运行,等待依赖服务恢复。
- 依赖恢复后,探针自动变更为
UP,Pod 重新接收流量。
3、Liveness Probe:生死判决官
3.1 核心作用
判断容器是否处于“无法自我修复的异常状态”。
- ❌ 检查失败:Kubernetes 会认为该容器已无法恢复,并立即重启容器。
- ✅ 检查成功:容器正常运行。
3.2 典型使用场景
- 进程僵死:如线程死锁,应用完全无响应。
- 内部故障:死循环、某些关键子系统崩溃导致主功能失效。
- 资源泄漏:内存泄漏导致应用逐渐卡顿至无响应。
⚠️ 重要提醒:
Liveness Probe 不适合 用于检查外部依赖(如数据库)的可用性。否则,一次短暂的网络抖动或数据库维护就可能导致你的应用被不停重启,引发更严重的问题。
3.3 示例配置(HTTP 探针)
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60 # 给予应用充足的启动时间
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 3
3.4 Spring Boot Liveness 示例
@Component
public class LivenessHealthIndicator implements HealthIndicator {
@Override
public Health health() {
if (threadPoolAlive() && mainLoopAlive()) {
return Health.up().build();
}
return Health.down().build();
}
}
4、Readiness 与 Liveness 核心区别对比
| 维度 |
Readiness (就绪探针) |
Liveness (存活探针) |
| 关注点 |
能否接收并处理流量 |
应用进程是否需要重启 |
| 失败后果 |
从 Service Endpoints 中摘除 |
容器被重启 |
| 是否影响 Pod 生命周期 |
否 |
是 |
| 是否适合检查外部依赖 |
✅ 是 |
❌ 否 |
| 是否适合检查内部死锁 |
❌ 否 |
✅ 是 |
一句话总结:Readiness 控制“流量开关”,Liveness 控制“容器生死”。
5、Readiness + preStop 实现真正的优雅下线
在进行滚动更新或缩容操作时,如果 Pod 被直接删除,正在处理的请求会被强制中断。结合 Readiness Probe 和 preStop 钩子,可以实现流量的平滑迁移与优雅下线,这是构建高可用服务的关键一环。
流程如下:
- 触发终止:Kubernetes 向 Pod 发送终止信号,并执行
preStop 钩子。
- 摘除流量:
preStop 钩子可先将应用的健康检查端点(如 Readiness)置为失败,使 Pod 立即从 Service 中摘除,不再接收任何新请求。
- 处理旧请求:等待一段预设时间(如10秒),让 Pod 完成现有请求的处理。
- 真正停止:随后容器被正常终止。
示例配置:
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 10"] # 等待10秒处理剩余请求
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
通过合理的运维流程与配置,可以极大减少发布和变更期间对用户的影响。
6、结合 Spring Boot Actuator 的完整配置
Spring Boot 2.3+ 版本对 Actuator 的健康端点进行了细化,原生支持独立的 Liveness 和 Readiness 状态,与 Kubernetes 探针理念完美契合。
application.yml 配置:
management:
endpoints:
web:
exposure:
include: health
health:
livenessstate:
enabled: true
readinessstate:
enabled: true
配置后,应用会暴露两个端点:
GET /actuator/health/liveness: 仅检查应用进程本身是否存活。
GET /actuator/health/readiness: 检查应用是否就绪(通常包含对数据库等关键依赖的检查)。
这使得 Spring Boot 应用在 Kubernetes 中的健康检查逻辑更加清晰、职责分明。
7、生产环境探针参数调优指南
| 参数 |
建议值 |
说明 |
| initialDelaySeconds |
Liveness: 60~120s<br>Readiness: 10~30s |
必须大于应用启动时间,避免启动过程中被误杀或误摘。 |
| periodSeconds |
5~15s |
检查频率。过于频繁会增加应用负担,太慢则会影响故障发现速度。 |
| timeoutSeconds |
1~5s |
单次探测请求的超时时间。 |
| failureThreshold |
3~5 |
连续失败多少次才判定为最终失败,避免因网络瞬时波动造成误判。 |
核心调优原则:
- Liveness 要“保守”:设置较长的
initialDelaySeconds 和适当的 failureThreshold,确保只在应用真正“无药可救”时才重启,避免频繁重启引发的雪崩。
- Readiness 可“积极”:可以相对快速地摘除不健康的 Pod,保护用户体验和系统整体稳定。
- 结合监控:探针参数需根据应用的实际启动时间、性能表现进行调整,并配合监控系统观察效果。
8、总结
正确地配置和使用 Readiness 与 Liveness 探针,是保障 Kubernetes 应用稳定性的基石。让我们再次回顾核心要点:
- Readiness 是流量开关,管理 Pod 何时能加入服务网格接收请求。
- Liveness 是生死判决,管理容器何时应被重启以尝试恢复。
- 优雅下线依赖于 Readiness Probe 与
preStop 钩子的协同工作。
- 生产调优的关键在于根据应用特性(如启动速度)合理设置
initialDelaySeconds、periodSeconds 等参数。
深入理解并实践这些概念,你的 云原生 应用将具备更强的自愈能力和更高的可用性。