10分钟搞定Spring Boot Actuator

  • 什么是 Spring Boot Actuator
  • 怎么使用?
  • 什么是端点(Endpoint)?
  • 如何使用端点
  • 启用
  • 暴露
  • 实现自定义 bean
  • 接受输入
  • 匹配方法 = http类型 + 参数
  • 响应类型
  • =================
  • 到这里10分钟入门结束
  • =================
  • 安全考虑
  • 访问控制
  • CORS 配置


什么是 Spring Boot Actuator

Spring Boot 包含许多附加特性,以帮助您在将应用程序推向生产环境时监视和管理它。您可以选择使用 HTTP 端点或 JMX 来管理和监视应用程序。审计、健康状况和度量标准收集也可以自动应用于您的应用程序。

怎么使用?

引入 starter 依赖即可:

maven项目:

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

gradle 项目

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
}

什么是端点(Endpoint)?

端点可以理解成应用的外部交互点. 如果你知道 jmx 的话, 就是 jmx 的管理接口, 也可以看作是获取应用信息的接口. 总而言之, 可以用来查看信息, 或者是在应用运行的时候从外部控制应用.

SpringBoot 有很多开箱即用的 端点. 比如 health 端点可以用来查看应用的运行状态信息.

如何使用端点

在 spring boot 配置中一启用, 二暴露. 也就是说 端点 = 启用 + 暴露

暴露 = JMX | Http. 既可以使用 JMX 方式使用, 也可以使用 Http 方式使用.

JMX 简单来说就是在 jdk8 中的那个 java mission control. windows上 win+R 输入 cmd , 然后 jmc 即可打开.

Http 的就是直接在浏览器上访问, 默认url 是 /actuator/{endpointId}

SpringBoot内置了很多端点, 比如说 beans端点 , 用来查看应用中所有 bean 的完整列表. 那么我们要用? 如果暴露了 http 方式 , 则浏览器中输入 "http://serverhost:port/actuator/bean" 即可查看了.

Spring Boot 的 Actuator_json

那么我怎么知道有哪些 端点可以用呢? 如果没有修改过管理员地址的话, 直接访问 "/actuator" 即可(http方式)

Spring Boot 的 Actuator_spring boot_02

启用

下面是启用 shutdown 端点的配置:

management.endpoint.shutdown.enabled=true

启用其他的话, 换个名字就行

除了 shutdown 端点, 其他的端点都是默认开启的.

下面是关闭默认开启, 并单独开启 info 端点的配置

management.endpoints.enabled-by-default=false
management.endpoint.info.enabled=true

暴露

每个 端点 也有默认的暴露配置, 有一些敏感信息不方便暴露, 所以暴露方式不同, 其默认的暴露配置也不同. 比如说 health 默认是 jmx 和 http 都暴露的. loggers 是默认 jmx 有暴露, http 没暴露.

属性

默认值

management.endpoints.jmx.exposure.exclude

management.endpoints.jmx.exposure.include

*

management.endpoints.web.exposure.exclude

management.endpoints.web.exposure.include

info, health

其中 jmx 的属性表示用暴露在 jmx, web表示要暴露在浏览器中.

默认情况下 jmx是所有端点都暴露了, 而 http 方式只有 info 和 health 能用, 所以别忘了在 include 中添加要暴露的端点.

实现自定义 bean

很简单, 在 类上 加上 @Bean@Endpoint 注解, 在 方法上加上 @ReadOperation, @WriteOperation, 或者 @DeleteOperation 注解.

会自动暴露在 JMX 和 Http 下.

@ReadOperation
public CustomData getCustomData() {
    return new CustomData("test", 5);
}

@JmxEndpoint@WebEndpoint 用来指定暴露方式.

也可以使用 @Controller 或者 @RestController 也可以使用 @ServletEndpoint 来将 Servlet 装换成 端点
也可以使用 @ControllerEndpoint@RestControllerEndpoint 来将 controller 转换成端点

接受输入

请求体:

{
    "name": "test",
    "counter": 42
}
@WriteOperation
public void updateCustomData(String name, int counter) {
    // injects "test" and 42
}

如果需要参数类型转换的话, 声明一个用 @EndpointConverter 修饰的 ApplicationConversionService 或者 Converter 或者 GenericConverter 的 bean

匹配方法 = http类型 + 参数

方法调用的http请求类型由注解决定:

Spring Boot 的 Actuator_Endpoint_03


按照我的理解, 它的匹配方式应该是这样的:

首先 http 请求来了之后, 先根据 http 类型(上面的 get,post, delete) 搭配注解决定是哪个方法, 然后再根据参数是否匹配, 匹配则调用对应的方法.

也就是说, 端点中用 @ReadOperation 注解的方法只能有一个(无论参数是否相同), 否则启动的时候会报错

比如我配置以下两个方法(无论参数是否相同)

Spring Boot 的 Actuator_json_04


Spring Boot 的 Actuator_Endpoint_05


参数一致需要一致

Spring Boot 的 Actuator_json_06

响应类型

响应的 ContentType 可以在注解里面指定

Spring Boot 的 Actuator_json_07


如果返回值为 void, 则 ContentType 为空

如果返回值为 org.springframework.core.io.Resource, ContentType 为 application/octet-stream. 其他情况为 application/vnd.spring-boot.actuator.v2+json, application/json如果直接返回实体类是不行的,会报错 No converter for class

Spring Boot 的 Actuator_spring boot_08


这种情况下, 如果需要响应json的话, 可以指定

@ReadOperation(produces = {"application/json"}), 这样可以直接返回json.否则需要声明转换器

=================

到这里10分钟入门结束

=================

安全考虑

访问控制

如果引入了 spring-security-starter , 就会默认开启访问控制, 需要通过代码开放权限:

允许 ENDPOINT_ADMIN 角色的用户访问

@Configuration(proxyBeanMethods = false)
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests((requests) ->
                requests.anyRequest().hasRole("ENDPOINT_ADMIN"));
        http.httpBasic();
    }

}

想裸奔的话:

@Configuration(proxyBeanMethods = false)
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests((requests) ->
            requests.anyRequest().permitAll());
    }

}

CORS 配置

默认关闭的这个功能, 一旦配了 management.endpoints.web.cors.allowed-origins 就会开启

management.endpoints.web.cors.allowed-origins
management.endpoints.web.cors.allowed-origins=https://example.com
management.endpoints.web.cors.allowed-methods=GET,POST