Spring Boot Actuator 配置和应用

一、Spring Boot Actuator简介

官方文档:https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html

Spring Boot Actuator(以下简称SBA)主要用于Spring Boot应用的健康检查,配合K8S可用于服务部署,切换流量,监控报警等场景。

1. 举个例子:

(1) 账户服务,线上运行版本为1.0.0,准备上线1.1.0,要求上线过程不可中断客户请求;为此,我们需要在保持1.0.0运行的同时部署1.1.0,在部署完1.1.0并且保证其已经Ready之后,我们让网关把部分/全部流量切换进来(前者属于灰度发布,后者是蓝绿发布)。如果这个过程是自动化的,我们如何让程序感知1.1.0版本已经Ready呢?注意,Ready这个状态未必仅指应用启动,可能启动之后还需要加载数据,或者有其他初始化工作,只有这些工作全部完成才算Ready。

Spring Boot Actuator的readiness接口便是为此而设计的。

(2) 用户服务,它强依赖于账户服务,我们希望当账户服务无法访问的情况下,用户服务可以感知,并且主动拒绝外部请求。针对这种场景,可通过自定义HealthIndicator的方式来实现。

2. 本文的应用对象为Kubernetes环境下的健康检查。

二、liveness和readiness

Kubernetes有两个Probes(探针, 请求者),分别是liveness和readiness。相应的SBA也提供了两个接口,分别是liveness和readiness。

1. liveness,表示Spring Boot应用的存活状态。SBA认为,liveness的状态不应依赖外部系统的状态,外部系统包括数据库、中间件、外部接口等;它仅仅表示应用本身是否活着。取值如下:

2. readiness,表示Spring Boot应用是否做好准备接受外部请求。SBA认为,readiness一定要考虑应用自身依赖的外部系统状态,例子2很好的说明了这一点。取值如下:

3. Spring Boot的生命周期

(1) 启动阶段

阶段 Liveness状态 Readiness状态 备注
Starting BROKEN REFUSING_TRAFFIC K8S检查"liveness"探针状态,如果长期没有影响,则重启服务。
Started CORRECT REFUSING_TRAFFIC 刷新Spring Boot应用上下文,执行其他启动任务,此时仍处于拒绝接受流量的状态。
Ready CORRECT ACCEPTING_TRAFFIC 启动完成,应用开始接受请求。

(2) 关闭阶段 

阶段 Liveness状态 Readiness状态 备注
Running live ready Shutdown开始执行。
Graceful shutdown live unready

所谓优雅的关闭,是指让已经进入应用的请求处理完毕,且在此阶段拒绝接受新的请求进入。

Shutdown complete broken unready 完成关闭。

三、监控什么?

我们需要监控的,一定是影响应用运行的因素。根据空间的划分,我们可以把监控目标分为本地依赖和远程依赖。

1. 本地依赖主要包括:

(1) 内存空间

(2) 硬盘空间

(3) 环境变量

(4) 配置文件

2. 远程依赖又可分为:

(1) 远程软件依赖,比如数据库、中间件、FTP或搜索引擎等;

(2) 远程接口依赖。

四、怎样监控?

1. 本地依赖

(1) 内存空间,假设应用实例出现内存溢出,我们应该设置应用的liveness状态为down,使调度器感知,发出报警,切换流量到其他实例,并重启该实例,这样可以避免线上出现宕机;

(2) 磁盘空间,如果应用需要保存大量文件到本地,就有必要监控磁盘空间占有量,如果空置率低到一定水平,应该设置应用的readiness状态为down,使调度器将请求切换到其他实例;

2. 远程依赖

(1) 软件依赖,至少需要从连通性上进行监控,如果发现无法连同,则需要设置应用的readiness状态为down,使调度器将请求切换到其他实例,或拒绝请求;

(2) 接口依赖,主要围绕着接口的连通性和可用性进行监控,如果接口服务可以提供readiness接口,可直接访问该接口来实现。

 五、Spring Boot Actuator重要概念

1. Endpoints

可以把Endpoints理解为一个功能模块,功能模块可以监控Spring Boot应用,甚至可以与Spring Boot进行交互(比如读取信息,关闭应用等操作)。Spring Boot内置了很多Endpoints,对我们来讲最重要的Endpoints是health,即健康检查模块。

除health外,常用的Endpoints还包括:

(1) env,用于输出环境变量;

(2) beans,用于显示应用中所有的bean对象;

(3) info,可以配置一些自定义信息。

a. 默认情况下,除shutdown以外,所有的Endpoints均是enable状态。如果希望disable所有Endpoints,可在application.properties中配置:

management.endpoints.enabled-by-default=false

b. 如果希望enable指定Endpoints,可配置:

management.endpoint.<name>.enabled=true

例如:

management.endpoint.info.enabled=true

c. 默认情况下,只有health和info两个Endpoints暴露在web环境下,可通过url访问,如果想暴露其他Endpoints,可配置:

management.endpoints.web.exposure.include=health,info,env

全部暴露可配置成*

management.endpoints.web.exposure.include=*

2. HealthIndicator(健康检查器)

从概念上讲,HealthIndicator从属于health这个Endpoints。

从代码上讲,它是一个接口,继承该接口并重写health方法便可自定义一个健康检查器。

根据依赖目标的不同,检查器也不相同,围绕着常见的依赖,Spring Boot内置了许多Indicator:

上面这些已经默认启动,下面这俩默认禁用。

 

首先,让我们看看这些自带HealthIndicator的继承关系:

以MongoHealthIndicator为例,让我们透过源码,看看这些HealthIndicator如何进行健康检查:

事实上,MongoHealthIndicator执行了一段Mongo命令"{ buildInfo: 1 }",以此来判断Mongo的连通性。

3. Health信息

(1) Spring Boot启动后,访问

http://<Spring Boot Domain>/actuator

即可查看该实例所有已经暴露到Web的Endpoints。

(2) 查看健康信息

/actuator/health

如果希望得到详细的健康信息,则添加配置:

management.endpoint.health.show-details=always

(3) Health状态

如果一切OK,则是UP状态;如果有依赖挂掉,则是DOWN状态。

(4) Health数据是如何产生的?

在(2)中我们看到,访问/actuator/health得到的是系统整体的健康信息。默认情况下,SBA自动enable了所有HealthIndicator。

如果想关掉所有默认打开的HealthIndicator,配置:

management.health.defaults.enabled=false

如果想enable指定的HealthIndicator,配置

management.health.<key>.enabled=true

key的取值参考五.2中的表格。 

4. 自定义HealthIndicator

(1) 官网例子

import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;

@Component
public class MyHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        int errorCode = check(); //执行健康检查

        if (errorCode != 0) {
            return Health.down().withDetail("Error Code", errorCode).build();
        }

        return Health.up().build();
    }
}

(2) 再来个栗子

假设我们的项目依赖https://api.github.com/

@Component
public class GitHubAPIHealthIndicator implements HealthIndicator {
    private final RestTemplate restTemplate;

    @Override
    public Health health() {
        try {
            ParameterizedTypeReference<Map<String, String>> reference = new ParameterizedTypeReference<Map<String, String>>() {};
            ResponseEntity<Map<String, String>> result = restTemplate.exchange("https://api.github.com/", HttpMethod.GET, null, reference);
if (result.getStatusCode().is2xxSuccessful() && result.getBody() != null) { return Health.up().withDetails(result.getBody()).build(); } else { return Health.down().withDetail("status", result.getStatusCode()).build(); } } catch (RestClientException ex) { return Health.down().withException(ex).build(); } } }

访问/actuator/health

 

5. Health Groups

(1) 如果你想将若干指定的HealthIndicator捆绑起来构成一组健康检查,那么可配置:

management.endpoint.health.group.custom.include=db

访问

/actuator/health/custom

即可获得custom这个组的健康状态。

(2) SBA创建了两个默认的组,liveness和readiness。

默认情况下,只有当Spring Boot应用部署到K8S内,才可以访问liveness和readiness接口,如果你希望在本地访问这两个接口,需要配置:

management.endpoint.health.probes.enabled=true

接口访问方式为:

/actuator/health/liveness/actuator/health/readiness

(3) 既然liveness和readiness也是Health Groups,那么我们就可以自定义它们包含的HealthIndicator对象:

management.endpoint.health.group.liveness.include=livenessState,customCheck
management.endpoint.health.group.readiness.include=readinessState,db

此时liveness会执行LivenessStateHealthIndicator和CustomCheckHealthIndicator两个检查器,readiness会执行ReadinessStateHealthIndicator和数据库检查。

三、基本配置和应用

1. pom引用

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

作为spring-boot-starter-parent自带的组件,我们无需指定它的版本号。

2. 在application.properties中添加配置

management.endpoints.web.exposure.include=info, health, env
management.endpoint.health.show-details=always
management.endpoint.health.probes.enabled=true
posted @ 2021-01-08 15:16  白马黑衣  阅读(5552)  评论(0编辑  收藏  举报