---
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