使用 Spring Boot 实现 Liveness 和 Readiness 探针

工程 | Brian Clozel | 2020 年 3 月 25 日 | ...

更新: 本博文已根据 Spring Boot 2.3.0.RC1 中发布的更改进行了更新

Spring Boot 团队正积极为即将发布的 2.3.0 版本开发 Kubernetes 主题。在增加了Docker 镜像创建优雅停机支持之后,现在是时候介绍 Liveness 和 Readiness 探针支持了。

在 2.2.0 版本中,Spring Boot 提供了健康分组支持,允许开发者选择一部分健康指标并将它们分组在一个单一、关联的健康状态下。

即使有了这个新特性,我们发现当涉及到 Kubernetes 时,我们可以为 Spring 社区提供更多、更具针对性的观点和指导。

Kubernetes 中的 Liveness 和 Readiness

在 Kubernetes 中,Liveness 和 Readiness 这两个 Kubernetes 概念代表了应用程序状态的不同方面。

应用程序的 Liveness 状态表示其内部状态是否有效。如果 Liveness 损坏,意味着应用程序本身处于失败状态且无法从中恢复。在这种情况下,最好的办法是重启应用程序实例。例如,依赖本地缓存的应用程序如果在本地缓存损坏且无法修复时,应该使其 Liveness 状态失败。

Readiness 状态表示应用程序是否已准备好接受客户端请求。如果 Readiness 状态未就绪,Kubernetes 不应将流量路由到该实例。如果应用程序正忙于处理任务队列,则可以声明自己处于忙碌状态,直到其负载再次可管理。

将 Liveness 和 Readiness 提升为核心 Spring Boot 概念

这些 Liveness 和 Readiness 概念不仅适用于 Kubernetes,它们在各种部署平台中都普遍有用。我们引入了 LivenessStateReadinessState,它们是这些概念的不可变表示。你可以随时从 ApplicationAvailability 中获取它们。

// Available as a component in the application context
ApplicationAvailability availability;

LivenessState livenessState = availabilityProvider.getLivenessState();
ReadinessState readinessState = availabilityProvider.getReadinessState()

仅依靠轮询检查来了解应用程序状态的模型是不完整的。只有应用程序自身了解其生命周期(启动、关闭)或能提供关于运行时错误的上下文(在处理任务时进入损坏状态)。Spring Boot 应用程序上下文会在应用程序生命周期期间原生发布这些事件;你的应用程序代码也应该能够对此做出贡献。

这就是为什么我们选择使用 Spring 应用事件模型来改变可用性状态并监听更新。

/**
 * Component that checks that the local cache is in a valid state.
 */
@Component
public class LocalCacheVerifier {

    private final ApplicationEventPublisher eventPublisher;

    public LocalCacheVerifier(ApplicationEventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
    }

    public void checkLocalCache() {
        try {
            //...
        }
        catch (CacheCompletelyBroken ex) {
            AvailabilityChangeEvent.publish(this.eventPublisher, ex, LivenessState.BROKEN);
        }
    }

}

组件也可以使用 @EventListener(或通过实现 ApplicationListener)来监听这些事件。请查看参考文档以获取更多信息

此支持直接包含在 spring-boot 模块中,并对所有 Spring Boot 应用程序激活;这使得它适用于所有类型的应用程序(Web、批处理等),并允许你实现不一定绑定到 HTTP 的探针。

使用 Spring Boot Actuator 暴露 Kubernetes 探针

你可能会对一个非常常见的用例感兴趣:在 Kubernetes 上部署 Web 应用程序并配置 HTTP 探针。唯一的要求是向你的应用程序添加 Spring Boot Actuator 依赖!Actuator 将利用 Health 支持来配置Liveness 和 Readiness HTTP 探针

Actuator 将从 ApplicationAvailability 中收集 “Liveness” 和 “Readiness” 信息,并在专用的健康指标中使用这些信息:LivenessStateHealthIndicatorReadinessStateHealthIndicator。这些指标将显示在全局健康端点("/actuator/health")上。它们还将作为单独的 HTTP 探针使用健康分组暴露:"/actuator/health/liveness""/actuator/health/readiness"

在 Kubernetes 上运行的应用程序将显示以下健康报告:

// http://localhost:8080/actuator/health
// HTTP/1.1 200 OK

{
  "status": "UP",
  "components": {
    "diskSpace": {
      "status": "UP",
      "details": { //...
      }
    },
    "livenessProbe": {
      "status": "UP"
    },
    "ping": {
      "status": "UP"
    },
    "readinessProbe": {
      "status": "UP"
    }
  },
  "groups": [
    "liveness",
    "readiness"
  ]
}

当调用 Liveness 分组时,Kubernetes 将获得以下信息:

// http://localhost:8080/actuator/health/liveness
// HTTP/1.1 200 OK

{
  "status": "UP",
  "components": {
    "livenessstate": {
      "status": "UP"
    }
  }
}

标记为未就绪的应用程序将为 Readiness 分组报告以下信息:

// http://localhost:8080/actuator/health/readiness
// HTTP/1.1 503 SERVICE UNAVAILABLE

{
  "status": "OUT_OF_SERVICE",
  "components": {
    "readinessstate": {
      "status": "OUT_OF_SERVICE"
    }
  }
}

HTTP 探针仅为在 Kubernetes 上运行的应用程序配置。你可以通过手动启用 management.health.probes.enabled=true 配置属性在本地尝试。由于探针是健康分组,你将获得许多额外的功能,例如配置 HTTP 状态映射器、安全性、详细信息可见性等…

你当然可以配置额外的健康指标作为探针的一部分,检查外部系统的状态:数据库、Web API、共享缓存。给定一个现有的 CacheCheckHealthIndicator,你可以通过以下方式增强 Liveness 探针:

management.endpoint.health.group.liveness.include=livenessstate,cacheCheck

你应该仔细考虑将外部状态与 Liveness 或 Readiness 关联起来,这就是为什么 Spring Boot 默认不添加任何内容的原因。每个应用程序和部署都不同,但我们致力于在社区的帮助下提供指导并调整默认设置——请查看我们参考文档中关于“使用 Kubernetes 探针检查外部状态”的部分

在 Spring Boot 2.3.0.RC1 中可用

结合优雅停机功能,此特性将有助于你管理 Kubernetes 中应用程序和容器的生命周期——我们已经在参考文档中开始提供关于 Kubernetes 部署和配置的指导

这个新功能将在我们即将发布的 2.3 里程碑版本中提供;我们期待收到你的反馈!

订阅 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

保持领先

VMware 提供培训和认证,助你快速进步。

了解更多

获取支持

Tanzu Spring 在一份简单的订阅中提供了 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部