--- title: SpringBoot Actuator 快速入门 date: 2022-06-14 20:51:22 order: 22 categories: - Java - 框架 - Spring - Spring其他 tags: - Java - 框架 - Spring - SpringBoot permalink: /pages/892679dd/ --- # SpringBoot Actuator 快速入门 [`spring-boot-actuator`](https://github.com/spring-projects/spring-boot/tree/v2.7.0/spring-boot-project/spring-boot-actuator) 模块提供了 Spring Boot 的所有生产就绪功能。启用这些功能的推荐方法是添加 `spring-boot-starter-actuator` 依赖。 如果是 Maven 项目,添加以下依赖: ```xml org.springframework.boot spring-boot-starter-actuator ``` 如果是 Gradle 项目,添加以下声明: ```groovy dependencies { implementation 'org.springframework.boot:spring-boot-starter-actuator' } ``` ## 端点(Endpoint) Actuator Endpoint 使 Spring Boot 用户可以监控应用,并和应用进行交互。Spring Boot 内置了许多 端点,并允许用户自定义端点。例如,`health` 端点提供基本的应用健康信息。 用户可以启用或禁用每个单独的端点并通过 HTTP 或 JMX 暴露它们(使它们可远程访问)。当端点被启用和公开时,它被认为是可用的。内置端点仅在可用时才会自动配置。大多数应用程序选择通过 HTTP 公开。例如,默认情况下,`health` 端点映射到 `/actuator/health`。 ### 启用端点 默认情况下,除了 `shutdown` 之外的所有端点都已启用。要配置端点的启用,请使用 `management.endpoint..enabled` 属性。以下示例启用 `shutdown` 端点: ```properties management.endpoint.shutdown.enabled=true ``` 如果您希望端点是明确指定才启用,请将 `management.endpoints.enabled-by-default` 属性设置为 false 并根据需要明确指定启用的端点,以下为示例: ```properties management.endpoints.enabled-by-default=false management.endpoint.info.enabled=true ``` ### 暴露端点 由于端点可能包含敏感信息,您应该仔细考虑何时暴露它们。下表显示了内置端点的默认曝光: | ID | JMX | Web | | :----------------- | :-- | :-- | | `auditevents` | Yes | No | | `beans` | Yes | No | | `caches` | Yes | No | | `conditions` | Yes | No | | `configprops` | Yes | No | | `env` | Yes | No | | `flyway` | Yes | No | | `health` | Yes | Yes | | `heapdump` | N/A | No | | `httptrace` | Yes | No | | `info` | Yes | No | | `integrationgraph` | Yes | No | | `jolokia` | N/A | No | | `logfile` | N/A | No | | `loggers` | Yes | No | | `liquibase` | Yes | No | | `metrics` | Yes | No | | `mappings` | Yes | No | | `prometheus` | N/A | No | | `quartz` | Yes | No | | `scheduledtasks` | Yes | No | | `sessions` | Yes | No | | `shutdown` | Yes | No | | `startup` | Yes | No | | `threaddump` | Yes | No | 要更改暴露的端点,请使用以下特定于技术的包含和排除属性: | Property | Default | | :------------------------------------------ | :------- | | `management.endpoints.jmx.exposure.exclude` | | | `management.endpoints.jmx.exposure.include` | `*` | | `management.endpoints.web.exposure.exclude` | | | `management.endpoints.web.exposure.include` | `health` | `include` 属性列出了暴露的端点的 ID。 `exclude` 属性列出了不应暴露的端点的 ID。 `exclude` 属性优先于 `include` 属性。您可以使用端点 ID 列表配置包含和排除属性。 例如,仅暴露 `health` 和 info 端点,其他端点都不通过 JMX 暴露,可以按如下配置: ```properties management.endpoints.jmx.exposure.include=health,info ``` 注意:`*` 可用于选择所有端点。 ### 安全 出于安全考虑,只有 `/health` 端点会通过 HTTP 方式暴露。用户可以通过 `management.endpoints.web.exposure.include` 决定哪些端点可以通过 HTTP 方式暴露。 如果 Spring Security 在类路径上并且不存在其他 `WebSecurityConfigurerAdapter` 或 `SecurityFilterChain` bean,则除 `/health` 之外的所有 actuator 都由 Spring Boot 自动启用安全控制。如果用户自定义了 `WebSecurityConfigurerAdapter` 或 `SecurityFilterChain` bean,Spring Boot 不再启用安全控制,由用户自行控制访问规则。 如果您希望为 HTTP 端点定义安全控制(例如,只允许具有特定角色的用户访问它们),Spring Boot 提供了一些方便的 `RequestMatcher` 对象,您可以将它们与 Spring Security 结合使用。 下面是一个典型的 Spring Security 配置示例: ```java @Configuration(proxyBeanMethods = false) public class MySecurityConfiguration { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.requestMatcher(EndpointRequest.toAnyEndpoint()) .authorizeRequests((requests) -> requests.anyRequest().hasRole("ENDPOINT_ADMIN")); http.httpBasic(); return http.build(); } } ``` 前面的示例使用 EndpointRequest.toAnyEndpoint() 将请求匹配到任何端点,然后确保所有端点都具有 ENDPOINT_ADMIN 角色。 EndpointRequest 上还提供了其他几种匹配器方法。 如果希望无需身份验证即可访问所有执行器端点。可以通过更改 management.endpoints.web.exposure.include 属性来做到这一点,如下所示: ```properties management.endpoints.web.exposure.include=* ``` 此外,如果存在 Spring Security,您将需要添加自定义安全配置,以允许未经身份验证的访问端点,如以下示例所示: ```java @Configuration(proxyBeanMethods = false) public class MySecurityConfiguration { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.requestMatcher(EndpointRequest.toAnyEndpoint()) .authorizeRequests((requests) -> requests.anyRequest().permitAll()); return http.build(); } } ``` 由于 Spring Boot 依赖于 Spring Security 的默认设置,因此 CSRF 保护默认开启。这意味着在使用默认安全配置时,需要 POST(关闭和记录器端点)、PUT 或 DELETE 的执行器端点会收到 403(禁止)错误。 > 建议仅在创建非浏览器客户端使用的服务时完全禁用 CSRF 保护。 ### 配置端点 端点会自动缓存对不带任何参数的读操作的响应数据。要配置端点缓存响应的时间量,请使用其 `cache.time-to-live` 属性。以下示例将 bean 端点缓存的生存时间设置为 10 秒: ```properties management.endpoint.beans.cache.time-to-live=10s ``` ### Actuator Web 端点的超媒体 Spring Boot Actuator 中内置了一个“发现页面”端点,其中包含了所有端点的链接。默认情况下,“发现页面”在 `/actuator` 上可用。 要禁用“发现页面”,请将以下属性添加到您的应用程序属性中: ```properties management.endpoints.web.discovery.enabled=false ``` 配置自定义管理上下文路径后,“发现页面”会自动从 `/actuator` 移动到应用管理上下文的根目录。例如,如果管理上下文路径是 `/management`,则发现页面可从 `/management` 获得。当管理上下文路径设置为 / 时,发现页面被禁用以防止与其他映射发生冲突的可能性。 ### 跨域支持 CORS 是一种 W3C 规范,可让用户以灵活的方式指定授权哪种跨域请求。如果使用 Spring MVC 或 Spring WebFlux,则可以配置 Actuator 的 Web 端点以支持此类场景。 CORS 支持默认是禁用的,只有在设置 `management.endpoints.web.cors.allowed-origins` 属性后才会启用。以下配置允许来自 example.com 域的 GET 和 POST 调用: ```properties management.endpoints.web.cors.allowed-origins=https://example.com management.endpoints.web.cors.allowed-methods=GET,POST ``` ### 自定义端点 如果添加带有 `@Endpoint` 注释的 `@Bean`,则任何带有 `@ReadOperation`、`@WriteOperation` 或 `@DeleteOperation` 注释的方法都会自动通过 JMX 公开,并且在 Web 应用程序中,也可以通过 HTTP 公开。可以使用 Jersey、Spring MVC 或 Spring WebFlux 通过 HTTP 公开端点。如果 Jersey 和 Spring MVC 都可用,则使用 Spring MVC。 以下示例公开了一个返回自定义对象的读取操作: ```java @ReadOperation public CustomData getData() { return new CustomData("test", 5); } ``` 您还可以使用 `@JmxEndpoint` 或 `@WebEndpoint` 编写特定技术的端点。这些端点仅限于各自的技术。例如,`@WebEndpoint` 仅通过 HTTP 而不是通过 JMX 公开。 您可以使用 `@EndpointWebExtension` 和 `@EndpointJmxExtension` 编写特定技术的扩展。这些注释让您可以提供特定技术的操作来扩充现有端点。 最后,如果您需要访问 Web 框架的功能,您可以实现 servlet 或 Spring `@Controller` 和 `@RestController` 端点,但代价是它们无法通过 JMX 或使用不同的 Web 框架获得。 ## 通过 HTTP 进行监控和管理 ### 自定义管理端点路径 如果是 Web 应用,Spring Boot Actuator 会自动将所有启用的端点通过 HTTP 方式暴露。默认约定是使用前缀为 `/actuator` 的端点的 id 作为 URL 路径。例如,健康被暴露为 `/actuator/health`。 有时,自定义管理端点的前缀很有用。例如,您的应用程序可能已经将 `/actuator` 用于其他目的。您可以使用 `management.endpoints.web.base-path` 属性更改管理端点的前缀,如以下示例所示: ```properties management.endpoints.web.base-path=/manage ``` 该示例将端点从 `/actuator/{id}` 更改为 `/manage/{id}`(例如,`/manage/info`)。 ### 自定义管理服务器端口 ```properties management.server.port=8081 ``` ### 配置 SSL 当配置为使用自定义端口时,还可以使用各种 `management.server.ssl.*` 属性为管理服务器配置自己的 SSL。例如,这样做可以让管理服务器在主应用程序使用 HTTPS 时通过 HTTP 可用,如以下属性设置所示: ```properties server.port=8443 server.ssl.enabled=true server.ssl.key-store=classpath:store.jks server.ssl.key-password=secret management.server.port=8080 management.server.ssl.enabled=false ``` 或者,主服务器和管理服务器都可以使用 SSL,但使用不同的密钥存储,如下所示: ```properties server.port=8443 server.ssl.enabled=true server.ssl.key-store=classpath:main.jks server.ssl.key-password=secret management.server.port=8080 management.server.ssl.enabled=true management.server.ssl.key-store=classpath:management.jks management.server.ssl.key-password=secret ``` ### 自定义管理服务器地址 ```properties management.server.port=8081 management.server.address=127.0.0.1 ``` ### 禁用 HTTP 端点 如果您不想通过 HTTP 方式暴露端点,可以将管理端口设置为 -1,如以下示例所示: ```properties management.server.port=-1 ``` 也可以通过使用 management.endpoints.web.exposure.exclude 属性来实现这一点,如以下示例所示: ```properties management.endpoints.web.exposure.exclude=* ``` ## 通过 JMX 进行监控和管理 Java 管理扩展 (JMX) 提供了一种标准机制来监视和管理应用程序。默认情况下,此功能未启用。您可以通过将 `spring.jmx.enabled` 配置属性设置为 true 来打开它。 Spring Boot 将最合适的 `MBeanServer` 暴露为 ID 为 `mbeanServer` 的 bean。使用 Spring JMX 注释(`@ManagedResource`、`@ManagedAttribute` 或 `@ManagedOperation`)注释的任何 bean 都会暴露给它。 如果您的平台提供标准 `MBeanServer`,则 Spring Boot 会使用该标准并在必要时默认使用 VM `MBeanServer`。如果一切都失败了,则创建一个新的 `MBeanServer`。 有关更多详细信息,请参阅 [`JmxAutoConfiguration`](https://github.com/spring-projects/spring-boot/tree/v2.7.0/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jmx/JmxAutoConfiguration.java) 类。 默认情况下,Spring Boot 还将管理端点公开为 `org.springframework.boot` 域下的 JMX MBean。要完全控制 JMX 域中的端点注册,请考虑注册您自己的 `EndpointObjectNameFactory` 实现。 ### 定制化 MBean Names MBean 的名称通常由端点的 id 生成。例如,健康端点公开为 `org.springframework.boot:type=Endpoint,name=Health`。 如果您的应用程序包含多个 Spring `ApplicationContext`,您可能会发现名称冲突。要解决此问题,您可以将 `spring.jmx.unique-names` 属性设置为 true,以便 MBean 名称始终是唯一的。 如果需要定制,跨域按如下配置: ```properties spring.jmx.unique-names=true management.endpoints.jmx.domain=com.example.myapp ``` ### 禁用 JMX 端点 想禁用 JMX 端点,可以按如下配置: ``` management.endpoints.jmx.exposure.exclude=* ``` ### 将 Jolokia 用于基于 HTTP 的 JMX Jolokia 是一个 JMX-HTTP 的桥接工具,它提供了另一种访问 JMX bean 的方法。要使用 Jolokia,需要先添加依赖: ```xml org.jolokia jolokia-core