SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客

文章目录

1.介绍

本篇中将介绍 Spring Boot 2.3 如何与 Kubernetes 探针集成以创建更愉快的云原生体验。

首先,将从 Kubernetes 探针的一些背景开始。 然后,看看 Spring Boot 2.3 如何支持这些探针。

2.Kubernetes探针

当使用 Kubernetes 作为我编排平台时,每个节点中的 kubelet 负责保持该节点中的 pod 健康。

例如,有时应用程序可能需要一点时间才能接受请求。 kubelet 可以确保应用程序仅在准备就绪时接收请求。 此外,如果 Pod 的主进程因任何原因崩溃,kubelet 将重新启动容器。

为了履行这些职责,Kubernetes 有两个探针:活性探针和就绪探针。

kubelet 将使用就绪探针来确定应用程序何时准备好接受请求。 更具体地说,当 pod 的所有容器都准备就绪时,它就准备好了。

类似地,kubelet 可以通过活性探针检查 pod 是否还活着。 基本上,活性探针可以帮助 kubelet 知道何时应该重新启动容器。

熟悉了这些概念,看看 Spring Boot 集成是如何工作的。

3.就绪探针和存活探针在Actuator

从 Spring Boot 2.3 开始,LivenessStateHealthIndicator 和 ReadinessStateHealthIndicator 类将公开应用程序的活跃度和就绪状态。 当将应用程序部署到 Kubernetes 时,Spring Boot 会自动注册这些健康指标。

因此,可以分别使用 /actuator/health/liveness 和 /actuator/health/readiness 端点作为liveness 和 readiness 探针。

例如,以将这些添加到 pod 定义中,以将活性探针配置为 HTTP GET 请求:

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

通常会让 Spring Boot 决定何时提供这些探针。 但是,如果愿意,可以在 application.properties 中手动启用它们。

如果使用 Spring Boot 2.3.0 或 2.3.1,可以通过配置属性启用上述探针:

management.health.probes.enabled=true

但是,从 Spring Boot 2.3.2 开始,由于配置混乱,不推荐使用此属性。

如果使用 Spring Boot 2.3.2,可以使用新属性来启用 liveness 和 readiness 探针:

management.endpoint.health.probes.enabled=true
management.health.livenessState.enabled=true
management.health.readinessState.enabled=true
management:
  endpoint:
    health:
      probes:
        enabled: true
  health:
    livenessstate:
      enabled: true
    readinessstate:
      enabled: true

3.1.就绪和活跃状态转换

Spring Boot 使用两个枚举来封装不同的就绪和活跃状态。 对于就绪状态,有一个名为 ReadinessState 的枚举,具有以下值:

  • ACCEPTING_TRAFFIC 状态表示应用程序已准备好接受流量
  • REFUSING_TRAFFIC 状态意味着应用程序还不愿意接受任何请求

同样,LivenessState 枚举使用两个值表示应用程序的活跃状态:

  • CORRECT 值表示应用程序正在运行并且其内部状态是正确的
  • 另一方面,BROKEN 值意味着应用程序运行时出现了一些致命故障

以下是 Spring 中应用程序生命周期事件方面的就绪和活跃状态如何变化:

  • 注册监听器和初始化器
  • 准备环境
  • 准备应用程序上下文
  • 加载 bean 定义
  • 将活动状态更改为 CORRECT
  • 调用应用程序和命令行运行程序
  • 将就绪状态更改为 ACCEPTING_TRAFFIC

一旦应用程序启动并运行,(和 Spring 本身)就可以通过发布适当的 AvailabilityChangeEvents 来更改这些状态。

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. 更新可用性状态

还可以通过发布 AvailabilityChangeEvent 事件来更新应用程序状态:

assertThat(applicationAvailability.getLivenessState())
  .isEqualTo(LivenessState.CORRECT);
mockMvc.perform(get("/actuator/health/liveness"))
  .andExpect(status().isOk())
  .andExpect(jsonPath("$.status").value("UP"));

AvailabilityChangeEvent.publish(context, LivenessState.BROKEN);

assertThat(applicationAvailability.getLivenessState())
  .isEqualTo(LivenessState.BROKEN);
mockMvc.perform(get("/actuator/health/liveness"))
  .andExpect(status().isServiceUnavailable())
  .andExpect(jsonPath("$.status").value("DOWN"));

如上所示,在发布任何事件之前,/actuator/health/liveness 端点使用以下 JSON 返回 200 OK 响应:

{
    "status": "OK"
}

然后在打破活跃状态后,同一个端点返回一个 503 服务不可用响应,其中包含以下 JSON:

{
    "status": "DOWN"
}

当更改为 REFUSING_TRAFFIC 的就绪状态时,状态值为 OUT_OF_SERVICE

assertThat(applicationAvailability.getReadinessState())
  .isEqualTo(ReadinessState.ACCEPTING_TRAFFIC);
mockMvc.perform(get("/actuator/health/readiness"))
  .andExpect(status().isOk())
  .andExpect(jsonPath("$.status").value("UP"));

AvailabilityChangeEvent.publish(context, ReadinessState.REFUSING_TRAFFIC);

assertThat(applicationAvailability.getReadinessState())
  .isEqualTo(ReadinessState.REFUSING_TRAFFIC);
mockMvc.perform(get("/actuator/health/readiness"))
  .andExpect(status().isServiceUnavailable())
  .andExpect(jsonPath("$.status").value("OUT_OF_SERVICE"));

4.2.监听变化

可以注册事件侦听器,以便在应用程序可用性状态更改时收到通知:

@Component
public class LivenessEventListener {
    
    @EventListener
    public void onEvent(AvailabilityChangeEvent<LivenessState> event) {
        switch (event.getState()) {
        case BROKEN:
            // notify others
            break;
        case CORRECT:
            // we're back
        }
    }
}

原网址: 访问
创建于: 2024-02-19 09:55:27
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论