Spring Boot Actuator EndPoints(官网文档解读)

Actuator EndPoints 定义

Actuator EndPoints 是 Spring Boot Actuator 提供的一组 RESTful 接口。这些接口可以让你深入了解应用程序的内部状态,比如健康状况、运行时指标、环境变量等。通过这些端点,运维人员和开发人员能够更好地监控应用运行,快速定位和解决问题,同时也方便进行性能调优。

EndPoints 分类

EndPoints 的访问端点可分为两类:一类是 Web 端点,另一类是 JMX 端点。用户可根据自身使用习惯选择相应的端点类型。

EndPoints 访问

  • Spring Boot 的 actuator 包含一系列内置端点,例如 /health。我们还可以通过代码编写和配置来自定义添加端点。

  • actuator 端点的 Web 访问格式为:项目访问地址 + /actuator + /EndPoints 端点。

  • 示例:以本地测试项目为例,若项目端口号为 8091,要访问 health 端点,请求地址为:

  • http://localhost:8091/actuator/health

引入依赖

若使用 Maven 构建项目,在pom.xml文件中添加如下依赖:

复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

EndPoints 全部端点列表

  • 默认开启的端点:引入 spring-boot-starter-actuator 依赖后,默认会开启 /health 端点,其他端点需进一步配置才能启用。

  • 查询已开启的端点列表:可通过访问 /actuator 来查询项目中已开启的全部端点列表,示例: http://localhost:8091/actuator

ID 描述
health 显示应用程序健康信息。
beans 显示应用程序中所有 Spring bean 的完整列表。
caches 公开可用的缓存。
info 显示任意应用程序信息。
conditions 显示对配置和自动配置类进行评估的条件以及它们匹配或不匹配的原因。
configprops 显示所有经过整理的列表@ConfigurationProperties。需进行清理。
env 公开 Spring 的 属性ConfigurableEnvironment。需经过清理。
loggers 显示和修改应用程序中记录器的配置。
heapdump 用于在运行时生成 Java 虚拟机(JVM)堆内存的快照,最终生成一个包含当前堆内存所有对象信息的二进制文件 heapdump.hprof
threaddump 执行线程转储。
metrics 显示当前应用程序的"指标"信息。
scheduledtasks 显示应用程序中的计划任务。
mappings 显示所有路径的整理列表@RequestMapping。
shutdown 让应用程序正常关闭。仅在使用 jar 打包时有效。默认情况下禁用。
flyway 显示已应用的任何 Flyway 数据库迁移。需要一个或多个Flywaybean。
httpexchanges 显示 HTTP 交换信息(默认情况下,显示最后 100 个 HTTP 请求-响应交换)。需要一个HttpExchangeRepositorybean。
integrationgraph 显示 Spring Integration 图。需要依赖spring-integration-core
liquibase 显示已应用的任何 Liquibase 数据库迁移。需要一个或多个Liquibasebean。
quartz 显示有关 Quartz Scheduler 作业的信息。需经过清理。
sessions 允许从 Spring Session 支持的会话存储中检索和删除用户会话。需要使用 Spring Session 的基于 servlet 的 Web 应用程序。
startup 显示收集的启动步骤数据ApplicationStartup。需要SpringApplication来配置BufferingApplicationStartup。
auditevents 公开当前应用程序的审计事件信息。需要一个AuditEventRepositorybean。

EndPoints 配置

修改默认的端点路径

要在Spring Boot应用程序中将默认的Actuator端点路径/actuator更改为自定义路径如/

management,我们可以这样配置:

复制代码
management:
  endpoints:
    web:
      base-path: /management

关闭端点发现页面

我们也可以直接将端点列表发现页面关闭,可以这样配置:

复制代码
management:
  endpoints:
    web:
      discovery:
        enabled: false

这个配置只会影响端点发现页面,对端点的正常使用没有影响。

开启所有Web端点

复制代码
# 开启所有默认Web端点
management:
  endpoints:
    web:
      exposure:
        include:  "*"

开启某些Web端点

复制代码
# 开启 info 和 env 端点
management:
  endpoints:
    web:
      exposure:
        include:  info,env

关闭某些Web端点

复制代码
# 开启全部端点,关闭info,env 端点
management:
  endpoints:
    web:
      exposure:
        include: "*"
        exclude:  info,env

开启所有JMX端点

开启所有默认JMX端点

复制代码
management:
  endpoints:
  jmx:
    exposure:
      include: "*"

关闭所有Web端点

复制代码
# 开启所有默认Web端点
management:
  endpoints:
    web:
      exposure:
        exclude: "*"

单独配置某个端点设置

我们可以使用 endpoint: 端点名的方式配置该端点的个性化配置。下面的示例即让health 端点显示更详细的信息。

复制代码
management:
  endpoint:
    health:
      show-details: always

端点缓存时间配置

端点自动缓存对不采用任何参数的读取操作的响应。要配置端点缓存响应的时间量,请使用其cache.time-To-live属性。下面的示例将bean端点缓存的生存时间设置为10秒:

复制代码
management:
  endpoint:
    beans:
      cache:
        time-to-live: "10s"

敏感值处理

/env/configprops/quartz端点返回的信息可能很敏感,因此默认情况下值总是被替换成***。我们可以通过修改端点的show-values配置,来改变值的显示。

复制代码
management:
  endpoint:
    env:
      show-values: always
  • 未配置前的展示:
  • 配置show-values 为always 的展示:
  • show-values 可配置属性:
属性配置值 含义
never 值始终被完全清理(替换为 ******)
always 值向所有用户展示(只要没有 SanitizingFunction bean 应用)
when-authorized 值仅向授权用户展示(只要没有 SanitizingFunction bean 应用)

跨域支持

跨域资源共享 (CORS) 是一项W3C 规范,可让您灵活地指定授权哪种跨域请求。如果您使用 Spring MVC 或 Spring WebFlux,则可以配置 Actuator 的 Web 端点以支持此类场景。

CORS 支持默认处于禁用状态,只有在您设置management.endpoints.web.cors.allowed-origins属性后才会启用。以下配置允许GETPOST从域中调用example.com

复制代码
management:
  endpoints:
    web:
      cors:
        allowed-origins: "https://example.com"
        allowed-methods: "GET,POST"

EndPoints 端点介绍

health 端点

  • 展示更详细的信息:下面的示例即让health 端点显示更详细的信息。
复制代码
management:
  endpoint:
    health:
      show-details: always
自动配置的健康指标

在适当的情况下,Spring Boot 会自动配置HealthIndicator下表中列出的 bean。您还可以通过配置启用或禁用选定的指标management.health.key.enabledkey下表列出了这些指标:

key 对应类 描述
cassandra CassandraDriverHealthIndicator 检查 Cassandra 数据库是否启动。
couchbase CouchbaseHealthIndicator 检查 Couchbase 集群是否启动。
db DataSourceHealthIndicator DataSource检查是否可以获得连接。
diskspace DiskSpaceHealthIndicator 检查磁盘空间是否不足。
elasticsearch ElasticsearchRestClientHealthIndicator 检查 Elasticsearch 集群是否启动。
hazelcast HazelcastHealthIndicator 检查 Hazelcast 服务器是否启动。
jms JmsHealthIndicator 检查 JMS 代理是否启动。
ldap LdapHealthIndicator 检查 LDAP 服务器是否启动。
mail MailHealthIndicator 检查邮件服务器是否启动。
mongo MongoHealthIndicator 检查 Mongo 数据库是否启动。
neo4j Neo4jHealthIndicator 检查 Neo4j 数据库是否启动。
ping PingHealthIndicator 总是以 回应UP
rabbit RabbitHealthIndicator 检查 Rabbit 服务器是否启动。
redis RedisHealthIndicator 检查 Redis 服务器是否启动。
ssl SslHealthIndicator 检查 SSL 证书是否正确。

接下来,我将用db 端点举例,来说明/health/{*path}的使用。如果想要/health包含/db 端点,我们需要引入数据源配置和java 数据库操作引擎。我的项目以mysql和jdbc 为例,需要在maven 中引入如下依赖:

复制代码
<!-- mysql 的驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- 添加 spring-boot-starter-jdbc 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

而后重新启动我们的项目,我们就可以获得db端点的健康检查输出了。

需手动配置的健康指标

默认情况下未启用的HealthIndicatorbean:

key 对应类 描述
livenessstate LivenessStateHealthIndicator 公开"Liveness"应用程序可用性状态。
readinessstate ReadinessStateHealthIndicator 公开"就绪"应用程序可用性状态。
自动配置的响应式健康指标
key 对应类 描述
cassandra CassandraDriverReactiveHealthIndicator 检查 Cassandra 数据库是否启动。
couchbase CouchbaseReactiveHealthIndicator 检查 Couchbase 集群是否启动。
elasticsearch ElasticsearchReactiveHealthIndicator 检查 Elasticsearch 集群是否启动。
mongo MongoReactiveHealthIndicator 检查 Mongo 数据库是否启动。
neo4j Neo4jReactiveHealthIndicator 检查 Neo4j 数据库是否启动。
redis RedisReactiveHealthIndicator 检查 Redis 服务器是否启动。
健康指标启用/禁用

我们可以使用health.defaults.enabled 属性来配置健康检查的端点细节是否启用。并可以配置/health端点的详细的key是否启用和禁用,如下示例关闭了/health 端点的细节展示,但放开了/db端点的细节展示。

复制代码
management:
  health:
    defaults:
      enabled: false
    db:
      enabled: true

编写一个自定义的健康指标
复制代码
package person.wend.springbootlearnexample2.health;

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

@Component
public class TestHealthIndicator implements HealthIndicator {

	@Override
	public Health health() {
		int errorCode = check();
		if (errorCode != 0) {
			return Health.down().withDetail("Error Code", errorCode).build();
		}
		return Health.up().build();
	}

	private int check() {
		// perform some specific health check
		return 899;
	}

}

该示例增加了一个 /health/test 端点的健康指标。

健康指标 status 状态定义
  • 下表显示了内置状态的默认状态映射:
地位 映射
DOWN SERVICE_UNAVAILABLE503
OUT_OF_SERVICE SERVICE_UNAVAILABLE503
UP 默认情况下没有映射,因此 HTTP 状态为200
UNKNOWN 默认情况下没有映射,因此 HTTP 状态为200
  • 自定义status 状态码映射

定义状态码映射

http-mapping:

up: 200

down: 503

out_of_serivce: 503

unknown: 200

  • 配置状态码顺序
复制代码
# 定义状态码映射
http-mapping:
  up: 200 
  down: 503 
  out_of_serivce: 503 
  unknown: 200
# 定义状态顺序
order:down, out_of_service, up, unknown
健康指标组定义

如下示例,定义了一个/custom 组端点,包含了健康指标的 db 端点。

复制代码
management:
  endpoint:
    health:
      group:
        custom:
          include: "db"

如下示例,定义了一个/custom 组端点,不包含健康指标的 db 端点。

复制代码
management:
  endpoint:
    health:
      group:
        custom:
          exclude: "db"

info 端点

自动配置的 InfoContributors
  • Spring 会自动配置以下InfoContributor Bean:
ID 对应类 描述 先决条件
build BuildInfoContributor 公开构建信息。 一种META-INF/build-info.properties资源。
env EnvironmentInfoContributor 公开Environment名称以 info开头的任何属性。 没有任何。
git GitInfoContributor 公开 git 信息。 一种git.properties资源。
java JavaInfoContributor 公开 Java 运行时信息。 没有任何。
os OsInfoContributor 公开操作系统信息。 没有任何。
process ProcessInfoContributor 公开流程信息。 没有任何。
ssl SslInfoContributor 公开 SSL 证书信息。 已配置SSL包。
  • 在初始化项目的时候,/info 端点展示的将是一个空json串。在这里,我将以/build 端点、/git 端点和/info端点为示例,讲述如何正确配置/info端点的子端点。

build 端点
  • 生成build端点的第一种方式是在resources的META-INF 资源文件夹下配置buid-info.properties。

  • 但我们一般采用使用maven 插件自动生成的方式:

    复制代码
              <plugin>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-maven-plugin</artifactId>
                  <executions>
                      <execution>
                          <goals>
                              <goal>build-info</goal>
                          </goals>
                      </execution>
                  </executions>
              </plugin>
git端点
  • git.properties文件一般配置在项目的根目录,我们可以手写生成该文件,但我们一般使用maven 插件自动生成的方式生成该文件。
复制代码
               <plugin>
                  <groupId>io.github.git-commit-id</groupId>
                  <artifactId>git-commit-id-maven-plugin</artifactId>
                  <version>5.0.0</version>
                  <executions>
                      <execution>
                          <id>get-the-git-infos</id>
                          <goals>
                              <goal>revision</goal>
                          </goals>
                      </execution>
                  </executions>
                  <configuration>
                      <dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
                      <generateGitPropertiesFile>true</generateGitPropertiesFile>
                      <generateGitPropertiesFilename>target/classes/git.properties</generateGitPropertiesFilename>
                  </configuration>
              </plugin>
  • 要想展示git 配置的更详细内容,可以做如下配置:

复制代码
  management:
    info:
      git:
        mode: "full"
  • git 端点展示效果如下图所示:

env端点
  • env 端点展示配置中以 info开头的任何属性。我们可以在application.yml 中做如下配置进行测试。
复制代码
info:
    app:
        name: ReD
        description: ReD
        version: 1.0.0
  • 在application.yml 中配置env.enabled =true,则最终会在页面中展示该配置。
启用/禁用
复制代码
# 开启所有默认Web端点
management:
  info:
    defaults:
      enabled: true
    env:
      enabled: true
    java:
      enabled: true
    build:
      enabled: false
  • 可以看到我们开启了/env,/java端点,关闭了/build 端点,最后/info端点的显示结果是这样的:

自定义/info子端点

  • 我们可以采用编码的方式,继承 InfoContributor,以实现定义自己的/info 子端点,示例代码如下:

    package person.wend.springbootlearnexample2.health;

    import org.springframework.boot.actuate.info.Info;
    import org.springframework.boot.actuate.info.InfoContributor;
    import org.springframework.stereotype.Component;

    import java.util.Collections;

    @Component
    public class TestInfoIndicator implements InfoContributor {
    @Override
    public void contribute(Info.Builder builder) {
    builder.withDetail("example", Collections.singletonMap("key", "value"));
    }
    }

  • 编写完成后,重启程序。最终会在/info 端点展示自行定义的内容

shutdown 端点

  • shutdown 端点配置
复制代码
management:
  endpoint:
    shutdown:
        enabled: true # 开启
        access: unrestricted #不受限制的访问shutdown端点
  • 使用示例
    • shutdown 端点是Post 请求,所以我使用了PostMan 模拟一个/actuator/shutdown 请求。请求后,运行的项目被正常关闭了。

prometheus端点

如果我们的项目中集成了prometheus,则可以通过如下配置开启/prometheus 端点。

复制代码
management:
  endpoints:
    web:
      prometheus:
        enabled: true

自定义EndPoints 端点

端点定义注解

@Endpoint

这是一个通用的端点定义注解,用于创建一个自定义端点,该端点可以同时支持 Web 和 JMX 两种访问方式。它允许开发者定义自己的管理端点,通过这些端点可以暴露应用程序的一些内部状态或执行特定的操作。

复制代码
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.stereotype.Component;

@Component
@Endpoint(id = "custom")
public class CustomEndpoint {

    @ReadOperation
    public String customInfo() {
        return "This is custom endpoint information.";
    }
}
@WebEndpoint

专门用于定义仅支持 Web 访问的自定义端点。如果你的端点只需要通过 HTTP 请求进行访问,使用该注解可以避免不必要的 JMX 相关配置。

复制代码
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.stereotype.Component;

@Component
@WebEndpoint(id = "webCustom")
public class WebCustomEndpoint {

    @ReadOperation
    public String webCustomInfo() {
        return "This is web custom endpoint information.";
    }
}
@JmxEndpoint

用于定义仅支持 JMX(Java Management Extensions)访问的自定义端点。如果你的应用程序需要通过 JMX 工具(如 VisualVM、JConsole 等)来管理和监控端点,就可以使用该注解。

复制代码
import org.springframework.boot.actuate.endpoint.jmx.annotation.JmxEndpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.stereotype.Component;

@Component
@JmxEndpoint(id = "jmxCustom")
public class JmxCustomEndpoint {

    @ReadOperation
    public String jmxCustomInfo() {
        return "This is JMX custom endpoint information.";
    }
}
@EndpointWebExtension

用于为现有的端点(可以是使用 @Endpoint 定义的端点)添加 Web 扩展功能。当你想要为一个已经存在的端点添加一些特定的 Web 访问逻辑时,可以使用这个注解。

复制代码
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension;
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpoint;
import org.springframework.boot.actuate.endpoint.web.annotation.ReadOperation;
import org.springframework.stereotype.Component;

@Endpoint(id = "original")
class OriginalEndpoint {
    @ReadOperation
    public String originalInfo() {
        return "Original endpoint information.";
    }
}

@Component
@EndpointWebExtension(endpoint = OriginalEndpoint.class)
public class OriginalEndpointWebExtension {

    @ReadOperation
    public String extendedInfo() {
        return "Extended information for original endpoint.";
    }
}
@EndpointJmxExtension

@EndpointWebExtension 类似,只不过它是为现有的端点添加 JMX 扩展功能,允许你为已有的端点增加特定的 JMX 访问逻辑。

操作注解

@ReadOperation

用于标记端点中的读操作方法。当客户端通过 HTTP GET 请求或 JMX 查询访问端点时,会调用被该注解标记的方法。通常用于获取端点的信息或状态。

@WriteOperation

用于标记端点中的写操作方法。当客户端通过 HTTP POST 请求访问端点时,会调用被该注解标记的方法。通常用于修改端点的某些配置或状态。

复制代码
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.stereotype.Component;

@Component
@Endpoint(id = "config")
public class ConfigEndpoint {

    private String configValue = "default";

    @WriteOperation
    public void updateConfig(String newValue) {
        this.configValue = newValue;
    }
}
@DeleteOperation

用于标记端点中的删除操作方法。当客户端通过 HTTP DELETE 请求访问端点时,会调用被该注解标记的方法。通常用于删除端点的某些资源或配置。

复制代码
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation;
import org.springframework.stereotype.Component;

@Component
@Endpoint(id = "resource")
public class ResourceEndpoint {

    @DeleteOperation
    public void deleteResource() {
        // 执行删除资源的操作
    }
}
  • 谓词的HTTP方法由操作类型决定,如下表所示:

|------------------|------------|
| 注解 | 对应的HTTP 方法 |
| @ReadOperation | GET |
| @WriteOperation | POST |
| @DeleteOperation | DELETE |

其他注解

@EndpointConverter

在自定义端点的开发过程中,端点方法可能会接收各种类型的参数。然而客户端传递过来的数据往往是字符串形式,此时就需要将这些字符串数据转换为端点方法所期望的具体类型。@EndpointConverter 注解的作用就是注册自定义的转换器,以此实现从字符串到特定类型的转换,保证端点方法能够正确接收和处理参数。

当你自定义端点方法需要接收非标准类型(例如自定义的枚举类型、复杂对象等)的参数,而 Spring Boot 又没有提供默认的转换器时,就可以使用 @EndpointConverter 注解来注册自定义的转换器。

@Selector

@Selector 注解起到的关键作用是让端点方法能接收动态路径变量,以此实现对特定资源的精准访问与操作。在开发自定义端点时,有时候需要根据不同的资源标识来执行特定操作。@Selector 注解能够将 URL 中的动态部分映射到端点方法的参数上,使得端点可以处理针对特定资源的请求。

  • 使用场景

    • 资源查询:根据特定资源的 ID 查询该资源的详细信息。

    • 资源修改:根据资源 ID 修改特定资源的属性。

    • 资源删除:根据资源 ID 删除特定资源。

  • 代码示例:

  • 定义自定义端点

    import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
    import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
    import org.springframework.stereotype.Component;

    import java.util.HashMap;
    import java.util.Map;

    // 定义一个自定义端点
    @Component
    @Endpoint(id = "custom-resources")
    public class CustomResourcesEndpoint {

    复制代码
      private final Map<String, String> resources = new HashMap<>();
    
      public CustomResourcesEndpoint() {
          resources.put("resource1", "Value for resource 1");
          resources.put("resource2", "Value for resource 2");
      }
    
      // 使用 @Selector 注解接收动态路径变量
      @ReadOperation
      public String getResource(@Selector String resourceId) {
          return resources.getOrDefault(resourceId, "Resource not found");
      }

    }

  • 访问端点

假设应用运行在 http://localhost:8080,可以通过以下 URL 访问特定资源:

  • http://localhost:8080/actuator/custom-resources/resource1

    • 返回 "Value for resource 1"
  • http://localhost:8080/actuator/custom-resources/resource2

    • 返回 "Value for resource 2"
  • http://localhost:8080/actuator/custom-resources/non-existent

    • 返回 "Resource not found"

Web 端点响应状态

端点操作的默认响应状态取决于操作类型(读取、写入或删除)以及操作返回的内容(如果有)。

  • @ReadOperation,有返回值,则响应状态为 200(OK)。如果没有返回值,则响应状态为 404(Not Found)。

  • @WriteOperation或@DeleteOperation:有返回值,则响应状态为 200(OK)。如果没有返回值,则响应状态为 204(No Content)。

  • 如果调用操作时没有指定必需参数或者指定了无法转换为所需类型的参数,则不会调用该操作方法,响应状态将为 400(错误请求)。

相关推荐
Pitayafruit5 小时前
📌 Java 工程师进阶必备:Spring Boot 3 + Netty 构建高并发即时通讯服务
spring boot·后端·netty
梦想实现家_Z5 小时前
SpringBoot实现MCP Server实战详解
spring boot·后端·mcp
遥不可及~~斌7 小时前
Spring Boot 项目日志系统全攻略:Logback、Log4j2、Log4j与SLF4J整合指南
spring boot·log4j·logback
爱的叹息7 小时前
Spring Boot 自定义配置类(包含字符串、数字、布尔、小数、集合、映射、嵌套对象)实现步骤及示例
java·linux·spring boot
!!!5259 小时前
Spring Boot 整合 MongoDB:分页查询详解 (新手友好)
spring boot·后端·mongodb
小杨4049 小时前
springboot框架项目实践应用十八(nacos高级特性)
spring boot·后端·spring cloud
菜鸟起航ing9 小时前
【Java面试系列】Spring Boot微服务架构下的分布式事务解决方案与性能优化详解 - 3-5年Java开发必备知识
java·spring boot·微服务·性能优化·分布式事务
XiaoLeisj11 小时前
【图书管理系统】深入解析基于 MyBatis 数据持久化操作:全栈开发图书管理系统:查询图书属性接口(注解实现)、修改图书属性接口(XML 实现)
xml·java·数据库·spring boot·sql·java-ee·mybatis
奔跑吧邓邓子11 小时前
使用 Spring Boot 和 Uniapp 搭建 NFC 读取系统
spring boot·uni-app·nfc数据读取
斜月11 小时前
springboot3与mybatisplus3.5.5 升级实践
spring boot·后端