【spring】 spring boot actuator 的使用与实现

分析 spring 如何使用及实现 actuator

actuator 是 spring boot 提供的对应用监控的功能,可以查看应用的配置以及运行信息。官方文档https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready

使用

在项目中引入 actuator

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

这时可以通过 http://127.0.0.1:8080/actuator 访问 actuator 打开的 endpoint,默认有 health 和 info

endpoint 配置

  • management.endpoint.shutdown.enabled=true
    是否要开 shutdown endpoint,打开的话可以通过这个 endpoint 关闭应用

主要有两大类 endpoint:通过 web 使用的 endpoint 和通过 jmx 使用的 endpoint

  • web 的配置在 WebEndpointProperties 类定义,主要的配置项有

    • management.endpoints.web.base-path
      定义 actuator 的访问路径, 默认是 /actuator

    • management.endpoints.web.exposure.include
      定义暴露哪些 endpoint,可以用 * 暴露所有的 endpoint

    • management.endpoints.web.exposure.exclude
      定义哪些 endpoint 不暴露

另外有 cors 的配置在 CorsEndpointProperties 类中定义

  • jmx 的配置在 JmxEndpointProperties 类定义
    • management.endpoints.jmx.domain
    • management.endpoints.jmx.exposure.include
    • management.endpoints.jmx.exposure.exclude

各个 endpoint 作用

  • health
    检查应用的运行状态,由 HealthEndpoint 类实现。运行状态由 HealthAggregator 实现,它会通过合并几个健康指数(例如 DataSourceHealthIndicator,DiskSpaceHealthIndicator 等)检查应用的健康情况,如果所有健康指数都是正常的话,返回的 status 是 UP,否则就是 DOWN 。 可以通过

    1
    management.health.diskspace.enable=false

    关闭部分检查(其中 diskspace 就组件名)

  • info
    获取应用程序的定制信息,这些信息由 info 打头的属性提供。例如在 application.properties 中定义一个 info.app.name,那么访问 info 这个 endpoint 时就显示 info.app.name 的值

  • loggers
    查看或修改日志级别。
    /loggers 可以查看所有 logger 的日志级别。/loggers/{name} 可以查看指定 logger 的日志级别,其中 configuredLevel 是配置的级别(可能为 null), effectiveLevel 是实际生效的级别。通过 POST {“configuredLevel”: {level}} 到 /loggers/{name} 可以修改 logger 的日志级别。

  • beans
    显示应用中所有的 bean 的定义。

  • conditions
    显示 spring boot auto-configuration 的所有 condition 是否生效。

    例如下面的返回结果表示 DataSourceAutoConfiguration 的条件匹配

    1
    2
    3
    4
    5
    6
    7
    DataSourceAutoConfiguration: [
    {
    condition: "OnClassCondition",
    message: "@ConditionalOnClass found required classes 'javax.sql.DataSource',
    'org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType'"
    }
    ]

    又例如下面的返回结果表示 RedisAutoConfiguration 的条件不匹配,找不到需要的 org.springframework.data.redis.core.RedisOperations 类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    RedisAutoConfiguration: {
    notMatched: [
    {
    condition: "OnClassCondition",
    message: "@ConditionalOnClass did not find required class 'org.springframework.data.redis.core.RedisOperations'"
    }
    ],
    matched: [ ]
    }
  • mappings
    描述应用的所有 URI

  • heapdump
    返回一个 heapdump

  • threaddump
    生成当前线程活动的快照

  • caches
    显示缓存信息

  • configprops
    描述配置属性(包含默认值)如何注入Bean

  • env
    获取全部环境属性

  • httptrace
    显示最近100个HTTP request/repsponse

  • metrics
    报告各种应用程序度量信息。metrics 这个 endpoint 显示了所有支持的 name,然后可以通过 /metrics/{name} 查看某一项的具体信息

  • auditevents
    显示应用暴露的审计事件

实现

endpoint 定义

要创建一个 endpoint 有两步,一是定义一个 endpoint bend,二是建立 endpoing 的访问路径。

  1. endpoint 就是有 @Endpoint 注解的 spring bean(endpoint 首先是 spring 容器管理的 bean),
    例如 BeansEndpoint。 spring boot 自带的 endpoint 都有对应的 AutoConfiguration 用来判断是否加载这个 endpoint。例如 BeansEndpoint 对应的就是 BeansEndpointAutoConfiguration, BeansEndpointAutoConfiguration 带有条件 @ConditionalOnEnabledEndpoint(endpoint = BeansEndpoint.class), 这个条件通过 OnEnabledEndpointCondition 计算结果, 表示如果有 management.endpoint.{endpoint id}.enabled=true 就个属性,条件就成立。

  2. 建立 endpoint 与建立 URI 的映射关系
    在引入的 spring-boot-actuator-autoconfigure 这个 jar 中包含有 WebEndpointAutoConfiguration,WebEndpointAutoConfiguration 定义了 bean WebEndpointDiscoverer。 WebEndpointDiscoverer 通过扫描 applicationContext 得到其中有 @Endpoint 注解的 bean。同时,spring-boot-actuator-autoconfigure 中包含有 WebMvcEndpointManagementContextConfiguration(依赖 DispatcherServlet 和 WebEndpointsSupplier, WebEndpointsSupplier 即 WebEndpointDiscoverer)。

    WebMvcEndpointManagementContextConfiguration 定义了 WebMvcEndpointHandlerMapping(HandlerMapping 的子类, 见 DispatcherServlet 的 getHandler 方法),而 WebMvcEndpointHandlerMapping 在 afterPropertiesSet 方法中将前面用 WebEndpointDiscoverer 加载出来的 endpoint 中的 operation 注册。

要自定义一个 endpoint,如下:

1
2
3
4
5
6
7
8
9
@Component
@Endpoint(id="hello")
public class HelloEndpoint {

@ReadOperation
public String hello() {
return "hello world";
}
}

之后可以通过 http://127.0.0.1:8080/actuator/hello 访问这个 endpoint

health 定义

health 这个 endpoint 用于检查应用的运行状态, 它的结果由多个 HealthIndicator 组合而成。 HealthIndicatorAutoConfiguration 定义了 HealthIndicatorRegistry,HealthIndicatorRegistry 从 applicationContext 找出所有实现了 HealthIndicator 接口和 ReactiveHealthIndicator (如果有用 Flex 的话) 的 bean 加入到 DefaultHealthIndicatorRegistry 的 healthIndicators 成员。

HealthEndpoint 被访问时, 会从遍历 healthIndicators 每个成员来计算状态。

示例

1
2
3
4
5
6
7
@Component
public class HelloHealthIndicator implements HealthIndicator {
@Override
public Health health() {
return Health.up().build();
}
}

可以通过 management.endpoint.health.show-details 设置能不能用 http://127.0.0.1:10080/actuator/health/{component} 访问组件的运行状态

metrics 定义

metrics 这个 endpoint 实际上是用 micrometer 实现(micrometer 类似 SLF4J, 是一个应用运行指标的门面)。 micrometer 自身就实现了很多内置的指标,由 org.springframework.boot.actuate.autoconfigure.metrics 包下的 @Configuration 类引入到 spring 容器,并注册到 MeterRegistry。

MetricsEndpoint 类实现了 metrics 这个 endpoint 的访问, endpoint 从 MeterRegistry 中找到对应的指标,并返回。