1. 概述

本文将介绍 Spring Boot 2.3 如何与 Kubernetes 的探针机制集成,进一步提升云原生应用的自愈能力与稳定性。

我们先简要回顾 Kubernetes 探针的基本概念,然后重点讲解 Spring Boot 2.3 是如何原生支持这些探针的。对于部署在 Kubernetes 中的 Spring Boot 应用来说,这是一项非常实用的功能,能有效避免“服务还没启动完就被流量打垮”这类经典踩坑场景。

2. Kubernetes 探针机制

在 Kubernetes 环境中,每个节点上的 kubelet 负责确保该节点上 Pod 的健康运行。

比如,应用启动时可能需要加载大量数据或建立数据库连接,短时间内无法处理请求。Kubernetes 通过 Readiness 探针来判断应用何时准备好接收流量。✅
而当应用内部陷入死锁或关键线程崩溃但进程仍在运行时,Liveness 探针则能帮助 kubelet 发现问题并重启容器,实现自我修复。✅

总结一下:

  • Readiness Probe(就绪探针):决定 Pod 是否加入服务负载均衡,即是否可以接收外部流量。
  • Liveness Probe(存活探针):判断应用是否“活着”,若失败则触发容器重启。

这两个探针通常通过 HTTP 接口、TCP 连接或执行命令的方式进行检测。

3. Spring Boot Actuator 中的 Liveness 与 Readiness 支持

从 Spring Boot 2.3 开始,框架内置了对这两种状态的原生支持,通过两个关键组件:

  • LivenessStateHealthIndicator
  • ReadinessStateHealthIndicator

这两个组件会自动暴露两个独立的接口:

  • GET /actuator/health/liveness → 用于 Liveness 探针
  • GET /actuator/health/readiness → 用于 Readiness 探针

配置示例

在 Kubernetes 的 Pod 配置中,你可以这样设置:

livenessProbe:
  httpGet:
    path: /actuator/health/liveness
    port: 8080
  initialDelaySeconds: 3
  periodSeconds: 3

readinessProbe:
  httpGet:
    path: /actuator/health/readiness
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5

⚠️ 注意:initialDelaySeconds 的值需要根据应用启动时间合理设置,太短会导致探针误判。

启用探针的配置方式

application.properties 中启用这些探针时,版本差异需要注意

  • Spring Boot 2.3.0 ~ 2.3.1

    management.health.probes.enabled=true
    
  • Spring Boot 2.3.2 及以上(推荐)

    management.endpoint.health.probes.enabled=true
    management.health.livenessState.enabled=true
    management.health.readinessState.enabled=true
    

❌ 自 2.3.2 起,旧属性已被废弃,原因是容易引起配置混淆(Issue #22107)。

3.1 状态流转机制

Spring Boot 使用两个枚举类来管理状态流转:

ReadinessState(就绪状态)

  • ACCEPTING_TRAFFIC:应用已准备好,可以接收流量 ✅
  • REFUSING_TRAFFIC:应用尚未就绪,拒绝流量 ❌

LivenessState(存活状态)

  • CORRECT:应用运行正常,内部状态健康 ✅
  • BROKEN:应用运行异常,需重启恢复 ❌

状态变更时机(按启动顺序)

  1. 注册监听器和初始化器
  2. 准备 Environment
  3. 准备 ApplicationContext
  4. 加载 Bean 定义
  5. 将 Liveness 状态置为 CORRECT
  6. 执行 ApplicationRunner 和 CommandLineRunner
  7. 将 Readiness 状态置为 ACCEPTING_TRAFFIC

这意味着:✅ 只有当所有初始化任务完成,Readiness 探针才会通过

你也可以在运行时通过发布 AvailabilityChangeEvent 来手动控制状态。

4. 应用可用性管理

你可以通过注入 ApplicationAvailability 接口来获取当前应用的健康状态:

@Autowired
private ApplicationAvailability applicationAvailability;

获取当前状态

assertThat(applicationAvailability.getLivenessState())
    .isEqualTo(LivenessState.CORRECT);

assertThat(applicationAvailability.getReadinessState())
    .isEqualTo(ReadinessState.ACCEPTING_TRAFFIC);

// 通用方法
assertThat(applicationAvailability.getState(ReadinessState.class))
    .isEqualTo(ReadinessState.ACCEPTING_TRAFFIC);

4.1 修改可用性状态

通过发布事件来改变状态,Spring 会自动更新对应接口的返回值。

模拟 Liveness 故障

// 初始状态
mockMvc.perform(get("/actuator/health/liveness"))
    .andExpect(status().isOk())
    .andExpect(jsonPath("$.status").value("UP"));

// 触发故障
AvailabilityChangeEvent.publish(context, LivenessState.BROKEN);

// 验证状态变化
mockMvc.perform(get("/actuator/health/liveness"))
    .andExpect(status().isServiceUnavailable()) // 503
    .andExpect(jsonPath("$.status").value("DOWN"));

此时 /actuator/health/liveness 返回:

{
    "status": "DOWN"
}

模拟服务下线(拒绝流量)

AvailabilityChangeEvent.publish(context, ReadinessState.REFUSING_TRAFFIC);

mockMvc.perform(get("/actuator/health/readiness"))
    .andExpect(status().isServiceUnavailable())
    .andExpect(jsonPath("$.status").value("OUT_OF_SERVICE"));

返回内容变为:

{
    "status": "OUT_OF_SERVICE"
}

这个机制非常适合用于灰度发布、优雅上下线等场景。

4.2 监听状态变化

你可以注册事件监听器,在状态变更时执行自定义逻辑:

@Component
public class LivenessEventListener {

    @EventListener
    public void onEvent(AvailabilityChangeEvent<LivenessState> event) {
        switch (event.getState()) {
            case BROKEN:
                // 发送告警、通知运维
                break;
            case CORRECT:
                // 恢复通知,可重新注册服务
                break;
        }
    }
}

同理,也可以监听 ReadinessState 的变化,比如在服务即将下线时关闭数据库连接池。

5. 自动配置原理

Spring Boot 通过 AvailabilityProbesAutoConfiguration 类实现自动装配。

该配置类会在以下任一条件满足时,自动注册 LivenessStateHealthIndicatorReadinessStateHealthIndicator

  • 当前运行环境为 Kubernetes
  • 配置项 management.endpoint.health.probes.enabled=true 被显式启用 ✅

🔍 判断是否运行在 Kubernetes 环境,是通过检测系统环境变量或文件路径(如 /var/run/secrets/kubernetes.io/)实现的。

这意味着:如果你的应用部署在 K8s 上,无需额外配置,Spring Boot 会自动开启这两个探针接口,非常省心。

6. 总结

Spring Boot 2.3+ 对 Kubernetes 探针的支持,是云原生实践中的一个简单粗暴但极其有效的功能:

  • ✅ 提供独立的 /actuator/health/liveness/actuator/health/readiness 接口
  • ✅ 自动识别 K8s 环境并启用探针
  • ✅ 支持运行时动态控制应用状态
  • ✅ 与 Kubernetes 原生探针机制无缝集成

合理使用这两个探针,可以显著提升微服务的稳定性和自愈能力,避免“假死”或“未启动完就被打垮”的问题。

所有示例代码均可在 GitHub 获取:https://github.com/tech-tutorial/spring-boot-actuator-probes


原始标题:Liveness and Readiness Probes in Spring Boot