跳到主要内容
版本:3.5.10

Endpoints

QWen Max 中英对照 Endpoints

Endpoints

Actuator 端点允许你监控和与应用程序进行交互。Spring Boot 内置了许多端点,并允许你添加自己的端点。例如,health 端点提供了基本的应用程序健康信息。

你可以控制每个单独端点的访问权限,并通过 HTTP 或 JMX 暴露它们(使其可远程访问)。当某个端点被允许访问并且已被暴露时,该端点就被视为可用。内置的端点仅在可用时才会自动配置。大多数应用程序选择通过 HTTP 暴露端点,此时端点的 ID 与前缀 /actuator 一起被映射到一个 URL。例如,默认情况下,health 端点会被映射到 /actuator/health

提示

要了解更多关于 Actuator 端点及其请求和响应格式的信息,请参阅 API 文档

以下技术无关的端点可用:

ID描述
auditevents暴露当前应用程序的审计事件信息。需要一个 AuditEventRepository Bean。
beans显示应用程序中所有 Spring Bean 的完整列表。
caches暴露可用的缓存。
conditions显示在配置类和自动配置类上评估的条件,以及它们匹配或不匹配的原因。
configprops显示所有 @ConfigurationProperties 的整合列表。受脱敏处理影响。
env暴露来自 Spring 的 ConfigurableEnvironment 的属性。受脱敏处理影响。
flyway显示已应用的 Flyway 数据库迁移。需要一个或多个 Flyway Bean。
health显示应用程序的健康状况信息。
httpexchanges显示 HTTP 交换信息(默认为最近 100 个 HTTP 请求-响应交换)。需要一个 HttpExchangeRepository Bean。
info显示任意的应用程序信息。
integrationgraph显示 Spring Integration 图。需要依赖 spring-integration-core
loggers显示并修改应用程序中日志记录器的配置。
liquibase显示已应用的 Liquibase 数据库迁移。需要一个或多个 Liquibase Bean。
metrics显示当前应用程序的“指标”信息,用于诊断应用程序已记录的指标。
mappings显示所有 @RequestMapping 路径的整合列表。
quartz显示有关 Quartz Scheduler 作业的信息。受脱敏处理影响。
scheduledtasks显示应用程序中的定时任务。
sessions允许从基于 Spring Session 的会话存储中检索和删除用户会话。需要使用 Spring Session 的基于 Servlet 的 Web 应用程序。
shutdown允许应用程序优雅关闭。仅在使用 jar 打包时有效。默认禁用。
startup显示由 ApplicationStartup 收集的启动步骤数据。需要将 SpringApplication 配置为使用 BufferingApplicationStartup
threaddump执行线程转储。

如果你的应用程序是一个 Web 应用程序(Spring MVC、Spring WebFlux 或 Jersey),你可以使用以下附加端点:

ID描述
heapdump返回堆转储文件。在 HotSpot JVM 上,返回 HPROF 格式的文件;在 OpenJ9 JVM 上,返回 PHD 格式的文件。
logfile返回日志文件的内容(前提是已设置 logging.file.namelogging.file.path 属性)。支持使用 HTTP Range 头来获取日志文件的部分内容。
prometheus以 Prometheus 服务器可抓取的格式暴露指标。需要依赖 micrometer-registry-prometheus

控制对端点的访问

默认情况下,除 shutdownheapdump 之外的所有端点的访问都是不受限制的。要配置对某个端点的允许访问权限,请使用其 management.endpoint.<id>.access 属性。以下示例允许对 shutdown 端点进行不受限制的访问:

management.endpoint.shutdown.access=unrestricted

如果你希望访问权限是“选择加入”(opt-in)而非“选择退出”(opt-out),请将 management.endpoints.access.default 属性设置为 none,并使用各个端点的 access 属性来重新启用访问。以下示例允许对 loggers 端点进行只读访问,并拒绝所有其他端点的访问:

management.endpoints.access.default=none
management.endpoint.loggers.access=read-only
备注

不可访问的端点会从应用程序上下文中完全移除。如果你只想更改端点暴露所使用的技术,请改用 include 和 exclude 属性

限制访问

可以通过 management.endpoints.access.max-permitted 属性来限制整个应用范围内的端点访问。该属性优先于默认访问级别或单个端点的访问级别。将其设置为 none 可使所有端点不可访问;设置为 read-only 则仅允许对端点进行读取访问。

对于 @Endpoint@JmxEndpoint@WebEndpoint,读取访问权限等同于使用 @ReadOperation 注解的端点方法。
对于 @ControllerEndpoint@RestControllerEndpoint,读取访问权限等同于能够处理 GETHEAD 请求的请求映射。
对于 @ServletEndpoint,读取访问权限等同于 GETHEAD 请求。

暴露端点

默认情况下,仅 health 端点通过 HTTP 和 JMX 暴露。由于端点可能包含敏感信息,你应该仔细考虑何时暴露它们。

要更改暴露的端点,请使用以下特定于技术的 includeexclude 属性:

属性默认值
management.endpoints.jmx.exposure.exclude
management.endpoints.jmx.exposure.includehealth
management.endpoints.web.exposure.exclude
management.endpoints.web.exposure.includehealth

include 属性列出了要暴露的端点 ID。exclude 属性列出了不应暴露的端点 ID。exclude 属性优先于 include 属性。你可以使用端点 ID 列表来配置 includeexclude 这两个属性。

例如,若要仅通过 JMX 暴露 healthinfo 端点,请使用以下属性:

management.endpoints.jmx.exposure.include=health,info

* 可用于选择所有端点。例如,要通过 HTTP 公开除 envbeans 端点外的所有内容,请使用以下属性:

management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=env,beans
备注

* 在 YAML 中具有特殊含义,因此如果你想包含(或排除)所有端点,请务必加上引号。

备注

如果你的应用程序是公开暴露的,我们强烈建议你同时 保护你的端点

提示

如果你想实现自己的策略来控制端点何时暴露,可以注册一个 EndpointFilter bean。

安全

出于安全考虑,默认情况下仅通过 HTTP 暴露 /health 端点。你可以使用 management.endpoints.web.exposure.include 属性来配置要暴露的端点。

备注

在设置 management.endpoints.web.exposure.include 之前,请确保所暴露的 Actuator 端点不包含敏感信息,或者通过将其置于防火墙之后,或使用类似 Spring Security 的机制进行保护。

如果 Spring Security 在 classpath 中,且没有其他 SecurityFilterChain bean 存在,则除了 /health 之外的所有 Actuator 端点都会被 Spring Boot 自动配置所保护。如果你定义了一个自定义的 SecurityFilterChain bean,Spring Boot 的自动配置将自动退出,让你完全控制 Actuator 的访问规则。

如果你希望为 HTTP 端点配置自定义安全策略(例如,仅允许具有特定角色的用户访问它们),Spring Boot 提供了一些便捷的 RequestMatcher 对象,可以与 Spring Security 结合使用。

一个典型的 Spring Security 配置可能如下例所示:

import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

import static org.springframework.security.config.Customizer.withDefaults;

@Configuration(proxyBeanMethods = false)
public class MySecurityConfiguration {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint());
http.authorizeHttpRequests((requests) -> requests.anyRequest().hasRole("ENDPOINT_ADMIN"));
http.httpBasic(withDefaults());
return http.build();
}

}

前面的示例使用 EndpointRequest.toAnyEndpoint() 来匹配到任意端点的请求,然后确保所有这些请求都具有 ENDPOINT_ADMIN 角色。EndpointRequest 上还提供了其他几种匹配器方法。详见 API 文档

如果你在防火墙后部署应用程序,你可能希望所有 Actuator 端点都可以无需认证即可访问。你可以通过修改 management.endpoints.web.exposure.include 属性来实现,如下所示:

management.endpoints.web.exposure.include=*

此外,如果存在 Spring Security,则需要添加自定义的安全配置,以允许对端点进行未经身份验证的访问,如下例所示:

import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration(proxyBeanMethods = false)
public class MySecurityConfiguration {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint());
http.authorizeHttpRequests((requests) -> requests.anyRequest().permitAll());
return http.build();
}

}
备注

在上述两个示例中,该配置仅适用于 actuator 端点。由于 Spring Boot 的安全配置在存在任何 SecurityFilterChain bean 时会完全退避,因此你需要额外配置一个 SecurityFilterChain bean,并为其设置适用于应用程序其余部分的规则。

跨站请求伪造保护

由于 Spring Boot 依赖于 Spring Security 的默认配置,CSRF 保护默认是开启的。这意味着当使用默认的安全配置时,需要 POST(如 shutdown 和 loggers 端点)、PUTDELETE 请求的 Actuator 端点会返回 403(Forbidden)错误。

备注

我们建议仅在你创建的服务由非浏览器客户端使用时,才完全禁用 CSRF 保护。

你可以在 Spring Security 参考指南 中找到有关 CSRF 保护的更多信息。

配置 Endpoints

端点会自动缓存不带任何参数的读取操作的响应。要配置端点缓存响应的时间长度,请使用其 cache.time-to-live 属性。以下示例将 beans 端点的缓存生存时间设置为 10 秒:

management.endpoint.beans.cache.time-to-live=10s
备注

management.endpoint.<name> 前缀唯一标识了正在配置的 endpoint。

敏感值脱敏

/env/configprops/quartz 端点返回的信息可能比较敏感,因此默认情况下,这些值始终会被完全脱敏(替换为 ******)。

只有在以下情况下,值才能以未经过滤的形式被查看:

  • show-values 属性被设置为除 never 之外的其他值

  • 没有适用的自定义 SanitizingFunction Bean

show-values 属性可以为可净化的端点配置为以下值之一:

  • never - 值始终被完全脱敏(替换为 ******

  • always - 值对所有用户可见(前提是没有任何 SanitizingFunction Bean 生效)

  • when-authorized - 值仅对授权用户可见(前提是没有任何 SanitizingFunction Bean 生效)

对于 HTTP 端点,如果用户已通过身份验证,并且拥有该端点 roles 属性所配置的角色,则认为该用户已被授权。默认情况下,任何已通过身份验证的用户都被视为已授权。

对于 JMX 端点,所有用户始终被授权。

以下示例允许具有 admin 角色的所有用户以原始形式查看 /env 端点中的值。未授权的用户或没有 admin 角色的用户将只能看到经过清理的值。

management.endpoint.env.show-values=when-authorized
management.endpoint.env.roles=admin
备注

此示例假定未定义任何 SanitizingFunction Bean。

执行器 Web 端点的超媒体

添加了一个“发现页面”,其中包含所有端点的链接。该“发现页面”默认在 /actuator 路径下可用。

要禁用 “discovery page”,请在你的应用属性中添加以下属性:

management.endpoints.web.discovery.enabled=false

当配置了自定义的 management context path 时,“discovery page”会自动从 /actuator 移动到 management context 的根路径。例如,如果 management context path 为 /management,则 discovery page 可通过 /management 访问。当 management context path 被设置为 / 时,discovery page 将被禁用,以防止与其他映射发生冲突。

CORS 支持

跨域资源共享(CORS)是一项 W3C 规范,它允许你以灵活的方式指定哪些跨域请求是被授权的。如果你使用 Spring MVC 或 Spring WebFlux,可以配置 Actuator 的 Web 端点以支持此类场景。

CORS 支持默认是禁用的,只有在设置了 management.endpoints.web.cors.allowed-origins 属性后才会启用。以下配置允许来自 example.com 域的 GETPOST 调用:

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

完整的选项列表请参见 CorsEndpointProperties

JSON

在处理 JSON 时,Jackson 被用于序列化和反序列化。默认情况下,会使用一个隔离的 ObjectMapper。这种隔离意味着它不会与应用程序的 ObjectMapper 共享相同的配置,并且不受 spring.jackson.* 属性的影响。要禁用此行为并配置 Actuator 使用应用程序的 ObjectMapper,请将 management.endpoints.jackson.isolated-object-mapper 设置为 false。或者,你也可以定义自己的 EndpointObjectMapper Bean,以生成符合你需求的 ObjectMapper。Actuator 随后将使用它进行 JSON 处理。

实现自定义端点

如果你添加一个使用 @Endpoint 注解的 @Bean,那么任何带有 @ReadOperation@WriteOperation@DeleteOperation 注解的方法都会自动通过 JMX 暴露出来,并且在 Web 应用程序中也会通过 HTTP 暴露。端点可以通过 Jersey、Spring MVC 或 Spring WebFlux 以 HTTP 方式暴露。如果同时存在 Jersey 和 Spring MVC,则会使用 Spring MVC。

以下示例公开了一个返回自定义对象的读取操作:

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

你也可以通过使用 @JmxEndpoint@WebEndpoint 来编写特定于技术的端点。这些端点仅限于各自对应的技术。例如,@WebEndpoint 仅通过 HTTP 暴露,而不会通过 JMX 暴露。

你可以使用 @EndpointWebExtension@EndpointJmxExtension 编写特定于技术的扩展。这些注解允许你提供特定于技术的操作,以增强现有的端点。每个端点最多只能有一种类型的扩展。

最后,如果你需要访问特定于 Web 框架的功能,你可以实现 Servlet 或 Spring 的 @Controller@RestController 端点,但代价是这些端点将无法通过 JMX 访问,也无法在使用其他 Web 框架时使用。

接收输入

端点上的操作通过其参数接收输入。当通过 Web 暴露时,这些参数的值取自 URL 的查询参数和 JSON 请求体。当通过 JMX 暴露时,参数会映射到 MBean 操作的参数。参数默认是必需的,可以通过使用 @javax.annotation.Nullable@Nullable 注解将其标记为可选。

你可以将 JSON 请求体中的每个根属性映射到端点的一个参数。考虑以下 JSON 请求体:

{
"name": "test",
"counter": 42
}

你可以使用它来调用一个写操作,该操作接受 String nameint counter 参数,如下例所示:

@WriteOperation
public void updateData(String name, int counter) {
// injects "test" and 42
}
提示

由于端点与技术无关,方法签名中只能指定简单类型。特别是,声明一个参数为 CustomData 类型(该类型定义了 namecounter 属性)是不被支持的。

备注

为了让输入能够映射到操作方法的参数,实现端点的 Java 代码应使用 -parameters 编译。对于 Kotlin 代码,请参阅 Spring Framework 参考文档中的建议。如果你使用 Spring Boot 的 Gradle 插件,或者使用 Maven 并基于 spring-boot-starter-parent,该设置将自动生效。

输入类型转换

传递给端点操作方法的参数(如有必要)会自动转换为所需的类型。在调用操作方法之前,通过 JMX 或 HTTP 接收到的输入会使用 ApplicationConversionService 的实例,以及任何使用 @EndpointConverter 注解限定的 ConverterGenericConverter Bean 转换为所需类型。

自定义 Web 端点

[@Endpoint](https://docs.spring.io/spring-boot/3.5.10/api/java/org/springframework/boot/actuate/endpoint/annotation/Endpoint.html)[@WebEndpoint](https://docs.spring.io/spring-boot/3.5.10/api/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpoint.html)[@EndpointWebExtension](https://docs.spring.io/spring-boot/3.5.10/api/java/org/springframework/boot/actuate/endpoint/web/annotation/EndpointWebExtension.html) 上的操作会通过 Jersey、Spring MVC 或 Spring WebFlux 自动暴露为 HTTP 接口。如果 Jersey 和 Spring MVC 同时可用,则使用 Spring MVC。

Web Endpoint 请求谓词

每个在 Web 暴露端点上的操作都会自动生成一个请求谓词(request predicate)。

路径

谓词的路径由端点的 ID 和 Web 暴露端点的基路径决定。默认的基路径是 /actuator。例如,ID 为 sessions 的端点在谓词中使用 /actuator/sessions 作为其路径。

你可以通过使用 @Selector 注解操作方法中的一个或多个参数,进一步自定义路径。这样的参数会作为路径变量添加到路径谓词中。当调用端点操作时,该变量的值会被传入操作方法。如果你想捕获所有剩余的路径元素,可以在最后一个参数上添加 @Selector(Match=ALL_REMAINING),并将其类型设置为与 String[] 兼容的转换类型。

HTTP 方法

谓词的 HTTP 方法由操作类型决定,如下表所示:

操作HTTP 方法
@ReadOperationGET
@WriteOperationPOST
@DeleteOperationDELETE

Consumes

对于使用请求体的 @WriteOperation(HTTP POST),谓词中的 consumes 子句为 application/vnd.spring-boot.actuator.v2+json, application/json。对于所有其他操作,consumes 子句为空。

Produces

谓词的 produces 子句可以通过 @DeleteOperation@ReadOperation@WriteOperation 注解的 produces 属性来确定。该属性是可选的。如果未使用该属性,则 produces 子句将自动确定。

如果操作方法返回 voidVoid,则 produces 子句为空。如果操作方法返回 Resource,则 produces 子句为 application/octet-stream。对于所有其他操作,produces 子句为 application/vnd.spring-boot.actuator.v2+json, application/json

Web 端点响应状态

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

如果一个 @ReadOperation 返回一个值,则响应状态码为 200(OK)。如果它不返回值,则响应状态码为 404(Not Found)。

如果一个 @WriteOperation@DeleteOperation 返回一个值,则响应状态码为 200(OK)。如果它不返回值,则响应状态码为 204(No Content)。

如果某个操作在调用时缺少必需的参数,或者提供的参数无法转换为所需的类型,则不会调用该操作方法,并且响应状态码将为 400(Bad Request)。

Web 端点范围请求

你可以使用 HTTP 范围请求(range request)来请求 HTTP 资源的一部分。在使用 Spring MVC 或 Spring WebFlux 时,返回 Resource 的操作会自动支持范围请求。

备注

使用 Jersey 时不支持范围请求(Range requests)。

Web Endpoint Security

对 Web 端点或 Web 特定的端点扩展的操作可以将当前的 PrincipalSecurityContext 作为方法参数接收。前者通常与 @javax.annotation.Nullable@Nullable 结合使用,以便为已认证和未认证用户提供不同的行为。后者通常通过其 isUserInRole(String) 方法执行授权检查。

Health Information

你可以使用健康信息来检查正在运行的应用程序的状态。监控软件通常会使用这些信息,在生产系统宕机时发出警报。health 端点所暴露的信息取决于 management.endpoint.health.show-detailsmanagement.endpoint.health.show-components 属性,这两个属性可配置为以下值之一:

名称描述
never从不显示详细信息。
when-authorized仅向授权用户显示详细信息。可以通过 management.endpoint.health.roles 配置授权角色。
always向所有用户显示详细信息。

默认值为 never。当用户属于端点的一个或多个角色时,该用户就被视为已授权。如果端点未配置任何角色(默认情况),则所有经过身份验证的用户都被视为已授权。你可以通过 management.endpoint.health.roles 属性来配置这些角色。

备注

如果你已对应用程序进行了安全保护,并希望使用 always,则你的安全配置必须允许已认证和未认证用户均可访问健康端点。

健康信息是从 HealthContributorRegistry 的内容中收集的(默认情况下,是你的 ApplicationContext 中定义的所有 HealthContributor 实例)。Spring Boot 包含了许多自动配置的 HealthContributor Bean,你也可以编写自己的实现。

一个 HealthContributor 可以是 HealthIndicatorCompositeHealthContributorHealthIndicator 提供实际的健康信息,包括一个 StatusCompositeHealthContributor 则提供其他 HealthContributor 实例的组合。这些贡献者共同构成一棵树形结构,用于表示整个系统的健康状况。

默认情况下,最终的系统健康状态由 StatusAggregator 派生得出,它会根据一个有序的状态列表对每个 HealthIndicator 返回的状态进行排序。排序后列表中的第一个状态将被用作整体健康状态。如果没有任何 HealthIndicator 返回的状态被 StatusAggregator 所识别,则使用 UNKNOWN 状态。

提示

你可以使用 HealthContributorRegistry 在运行时注册和注销健康指标。

自动配置的 HealthIndicators

在适当的情况下,Spring Boot 会自动配置下表中列出的 HealthIndicator Bean。你也可以通过配置 management.health.key.enabled 来启用或禁用特定的指示器,其中 key 为下表中列出的键:

KeyNameDescription
cassandraCassandraDriverHealthIndicator检查 Cassandra 数据库是否正常运行。
couchbaseCouchbaseHealthIndicator检查 Couchbase 集群是否正常运行。
dbDataSourceHealthIndicator检查是否可以获取到 DataSource 的连接。
diskspaceDiskSpaceHealthIndicator检查磁盘空间是否不足。
elasticsearchElasticsearchRestClientHealthIndicator检查 Elasticsearch 集群是否正常运行。
hazelcastHazelcastHealthIndicator检查 Hazelcast 服务器是否正常运行。
jmsJmsHealthIndicator检查 JMS 代理是否正常运行。
ldapLdapHealthIndicator检查 LDAP 服务器是否正常运行。
mailMailHealthIndicator检查邮件服务器是否正常运行。
mongoMongoHealthIndicator检查 Mongo 数据库是否正常运行。
neo4jNeo4jHealthIndicator检查 Neo4j 数据库是否正常运行。
pingPingHealthIndicator始终返回 UP
rabbitRabbitHealthIndicator检查 Rabbit 服务器是否正常运行。
redisRedisHealthIndicator检查 Redis 服务器是否正常运行。
sslSslHealthIndicator检查 SSL 证书是否正常。
提示

你可以通过设置 management.health.defaults.enabled 属性来全部禁用它们。

提示

ssl HealthIndicator 提供了一个名为 management.health.ssl.certificate-validity-warning-threshold 的“警告阈值”属性。你可以利用该阈值为自己预留充足的时间来轮换即将过期的证书。如果某个 SSL 证书将在该阈值所定义的时间段内失效,HealthIndicator 将在其响应的 details 部分中报告此情况,其中 details.validChains.certificates.[*].validity.status 的值将为 WILL_EXPIRE_SOON

额外的 HealthIndicator Bean 可用,但默认未启用:

KeyNameDescription
livenessstateLivenessStateHealthIndicator暴露应用程序的 “Liveness” 可用性状态。
readinessstateReadinessStateHealthIndicator暴露应用程序的 “Readiness” 可用性状态。

编写自定义 HealthIndicators

要提供自定义的健康信息,你可以注册实现了 HealthIndicator 接口的 Spring Bean。你需要实现 health() 方法并返回一个 Health 响应。该 Health 响应应包含一个状态,并可选择性地包含额外的详细信息以供显示。以下代码展示了一个示例 HealthIndicator 实现:

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

@Component
public class MyHealthIndicator 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 ...
}

}
备注

给定 HealthIndicator 的标识符是该 Bean 的名称(如果存在的话,去掉 HealthIndicator 后缀)。在前面的示例中,健康信息位于名为 my 的条目中。

提示

健康指标通常通过 HTTP 调用,并且需要在任何连接超时之前作出响应。Spring Boot 会为响应时间超过 10 秒的任何健康指标记录一条警告消息。如果你想配置此阈值,可以使用 management.endpoint.health.logging.slow-indicator-threshold 属性。

除了 Spring Boot 预定义的 Status 类型之外,Health 还可以返回一个自定义的 Status,以表示一种新的系统状态。在这种情况下,你还需要提供 StatusAggregator 接口的自定义实现,或者通过使用 management.endpoint.health.status.order 配置属性来配置默认实现。

例如,假设你在某个 HealthIndicator 实现中使用了一个代码为 FATAL 的新 Status。要配置严重性顺序,请在你的应用属性中添加以下配置:

management.endpoint.health.status.order=fatal,down,out-of-service,unknown,up

响应中的 HTTP 状态码反映了整体健康状态。默认情况下,OUT_OF_SERVICEDOWN 映射为 503。任何未映射的健康状态(包括 UP)都映射为 200。如果你通过 HTTP 访问 health 端点,可能还希望注册自定义的状态码映射。配置自定义映射会禁用 DOWNOUT_OF_SERVICE 的默认映射。如果你想保留默认映射,则必须在配置自定义映射的同时显式地重新配置这些默认映射。例如,以下属性将 FATAL 映射为 503(服务不可用),并保留 DOWNOUT_OF_SERVICE 的默认映射:

management.endpoint.health.status.http-mapping.down=503
management.endpoint.health.status.http-mapping.fatal=503
management.endpoint.health.status.http-mapping.out-of-service=503
提示

如果你需要更多控制,可以定义你自己的 HttpCodeStatusMapper bean。

下表显示了内置状态的默认状态映射:

状态映射
DOWNSERVICE_UNAVAILABLE (503)
OUT_OF_SERVICESERVICE_UNAVAILABLE (503)
UP默认无映射,因此 HTTP 状态码为 200
UNKNOWN默认无映射,因此 HTTP 状态码为 200

响应式健康指标

对于响应式应用程序(例如使用 Spring WebFlux 的应用程序),ReactiveHealthContributor 提供了一种非阻塞的方式来获取应用程序的健康状况。与传统的 HealthContributor 类似,健康信息从 ReactiveHealthContributorRegistry 的内容中收集(默认情况下,包括在您的 ApplicationContext 中定义的所有 HealthContributorReactiveHealthContributor 实例)。那些不针对响应式 API 进行检查的常规 HealthContributor 实例将在弹性调度器(elastic scheduler)上执行。

提示

在响应式应用中,你应该使用 ReactiveHealthContributorRegistry 在运行时注册和注销健康指标。如果你需要注册一个普通的 HealthContributor,应使用 ReactiveHealthContributor#adapt 对其进行包装。

要从响应式 API 提供自定义的健康信息,你可以注册实现 ReactiveHealthIndicator 接口的 Spring Bean。以下代码展示了一个 ReactiveHealthIndicator 的示例实现:

import reactor.core.publisher.Mono;

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

@Component
public class MyReactiveHealthIndicator implements ReactiveHealthIndicator {

@Override
public Mono<Health> health() {
return doHealthCheck().onErrorResume((exception) ->
Mono.just(new Health.Builder().down(exception).build()));
}

private Mono<Health> doHealthCheck() {
// perform some specific health check
return ...
}

}
提示

要自动处理该错误,可以考虑继承 AbstractReactiveHealthIndicator

自动配置的 ReactiveHealthIndicators

在适当的情况下,Spring Boot 会自动配置以下 ReactiveHealthIndicator Bean:

KeyNameDescription
cassandraCassandraDriverReactiveHealthIndicator检查 Cassandra 数据库是否正常运行。
couchbaseCouchbaseReactiveHealthIndicator检查 Couchbase 集群是否正常运行。
elasticsearchElasticsearchReactiveHealthIndicator检查 Elasticsearch 集群是否正常运行。
mongoMongoReactiveHealthIndicator检查 Mongo 数据库是否正常运行。
neo4jNeo4jReactiveHealthIndicator检查 Neo4j 数据库是否正常运行。
redisRedisReactiveHealthIndicator检查 Redis 服务器是否正常运行。
提示

如有必要,响应式指标会替换常规指标。此外,任何未被显式处理的 HealthIndicator 都会被自动包装。

健康检查组

有时将健康指标组织成组会很有用,你可以将这些组用于不同的目的。

要创建一个健康指标组,你可以使用 management.endpoint.health.group.<name> 属性,并指定一个健康指标 ID 列表用于 include(包含)或 exclude(排除)。例如,要创建一个仅包含数据库相关指标的组,可以定义如下内容:

management.endpoint.health.group.custom.include=db

然后你可以通过访问 [localhost:8080/actuator/health/custom](http://localhost:8080/actuator/health/custom) 来检查结果。

同样地,若要创建一个排除数据库指标、但包含所有其他指标的组,你可以定义如下内容:

management.endpoint.health.group.custom.exclude=db

默认情况下,如果健康检查组包含或排除了一个不存在的健康指示器,启动将会失败。要禁用此行为,请将 management.endpoint.health.validate-group-membership 设置为 false

默认情况下,组会继承与系统健康状况相同的 StatusAggregatorHttpCodeStatusMapper 设置。不过,你也可以为每个组单独定义这些设置。如果需要,还可以覆盖 show-detailsroles 属性:

management.endpoint.health.group.custom.show-details=when-authorized
management.endpoint.health.group.custom.roles=admin
management.endpoint.health.group.custom.status.order=fatal,up
management.endpoint.health.group.custom.status.http-mapping.fatal=500
management.endpoint.health.group.custom.status.http-mapping.out-of-service=500
提示

如果你需要为该组注册自定义的 StatusAggregatorHttpCodeStatusMapper Bean,可以使用 @Qualifier("groupname")

健康组还可以包含/排除一个 CompositeHealthContributor。你也可以仅包含/排除 CompositeHealthContributor 中的某个特定组件。这可以通过使用该组件的全限定名来实现,如下所示:

management.endpoint.health.group.custom.include="test/primary"
management.endpoint.health.group.custom.exclude="test/primary/b"

在上面的示例中,custom 组将包含名为 primaryHealthContributor,而 primary 是复合组件 test 的一部分。此处,primary 本身也是一个复合组件,因此名为 bHealthContributor 将被排除在 custom 组之外。

健康组可以在主端口或管理端口上通过一个额外的路径提供。这在 Kubernetes 等云环境中非常有用,因为在这些环境中,出于安全考虑,通常会为 Actuator 端点使用单独的管理端口。使用单独的端口可能导致健康检查不可靠,因为即使健康检查成功,主应用程序仍可能无法正常工作。可以通过如下方式为健康组配置一个额外的路径:

management.endpoint.health.group.live.additional-path="server:/healthz"

这将使 live 健康检查组在主服务器端口的 /healthz 路径上可用。前缀是必需的,必须为 server:(表示主服务器端口)或 management:(表示管理端口,如果已配置)。路径必须是单个路径段。

DataSource Health

DataSource 健康指示器会显示标准数据源和路由数据源 Bean 的健康状况。路由数据源的健康状况包含其每个目标数据源的健康状况。在健康端点的响应中,路由数据源的每个目标都以其路由键命名。如果你希望不在指示器的输出中包含路由数据源,请将 management.health.db.ignore-routing-data-sources 设置为 true

Kubernetes Probes

部署在 Kubernetes 上的应用程序可以通过 Container Probes 提供其内部状态的信息。根据 你的 Kubernetes 配置,kubelet 会调用这些探针并对结果作出响应。

默认情况下,Spring Boot 会管理你的 Application Availability 状态。如果部署在 Kubernetes 环境中,Actuator 会从 ApplicationAvailability 接口收集 “Liveness”(存活状态)和 “Readiness”(就绪状态)信息,并在专用的 健康指标 中使用这些信息:LivenessStateHealthIndicatorReadinessStateHealthIndicator。这些指标会显示在全局健康端点("/actuator/health")上。同时,它们也会通过 健康组 以独立的 HTTP 探针形式暴露出来:"/actuator/health/liveness""/actuator/health/readiness"

然后,你可以使用以下端点信息来配置你的 Kubernetes 基础设施:

livenessProbe:
httpGet:
path: "/actuator/health/liveness"
port: <actuator-port>
failureThreshold: ...
periodSeconds: ...

readinessProbe:
httpGet:
path: "/actuator/health/readiness"
port: <actuator-port>
failureThreshold: ...
periodSeconds: ...
备注

<actuator-port> 应设置为 Actuator 端点所在的端口。它可以是主 Web 服务器端口,或者如果设置了 "management.server.port" 属性,则可以是单独的管理端口。

这些健康检查组仅在应用程序 运行于 Kubernetes 环境中 时自动启用。你可以通过使用 management.endpoint.health.probes.enabled 配置属性在任意环境中启用它们。

备注

如果应用程序的启动时间超过了配置的存活期(liveness period),Kubernetes 会建议使用 "startupProbe" 作为可能的解决方案。一般来说,此处不一定需要 "startupProbe",因为 "readinessProbe" 会在所有启动任务完成之前一直失败,这意味着你的应用程序在准备就绪之前不会接收到任何流量。然而,如果你的应用程序启动时间较长,请考虑使用 "startupProbe",以确保 Kubernetes 在应用程序启动过程中不会将其杀死。参见 探针在应用程序生命周期中的行为 一节。

如果你的 Actuator 端点部署在独立的管理上下文中,这些端点将不会与主应用程序共享相同的 Web 基础设施(端口、连接池、框架组件)。在这种情况下,即使主应用程序无法正常工作(例如,无法接受新连接),探针检查仍可能成功。因此,建议将 livenessreadiness 健康组暴露在主服务器端口上。这可以通过设置以下属性来实现:

management.endpoint.health.probes.add-additional-paths=true

这将使 liveness 组在主服务器端口的 /livez 路径下可用,而 readiness 组在 /readyz 路径下可用。可以通过每个组的 additional-path 属性自定义路径,详情请参见 health groups

使用 Kubernetes 探针检查外部状态

Actuator 将 “liveness” 和 “readiness” 探针配置为健康检查组(Health Groups)。这意味着所有 健康检查组特性 对它们都可用。例如,你可以配置额外的 Health Indicator:

management.endpoint.health.group.readiness.include=readinessState,customCheck

默认情况下,Spring Boot 不会将其他健康指标添加到这些组中。

“liveness” 探针不应依赖于对外部系统的健康检查。如果 应用程序的 liveness 状态 出现故障,Kubernetes 会尝试通过重启应用程序实例来解决该问题。这意味着,如果某个外部系统(例如数据库、Web API 或外部缓存)发生故障,Kubernetes 可能会重启所有应用程序实例,从而引发级联故障。

至于 “readiness” 探针,应用程序开发者必须谨慎选择是否检查外部系统。出于这个原因,Spring Boot 不会在 readiness 探针中包含任何额外的健康检查。如果某个应用实例的 readiness 状态 为未就绪(unready),Kubernetes 就不会将流量路由到该实例。某些外部系统可能并非由所有应用实例共享,在这种情况下,可以将其纳入 readiness 探针中。而另一些外部系统可能对应用并非至关重要(例如,应用可能使用了断路器和降级机制),那么这些系统显然不应包含在 readiness 探针中。不幸的是,由所有应用实例共享的外部系统十分常见,此时你必须自行判断:是将其包含在 readiness 探针中,并接受当外部服务宕机时应用实例被移出服务;还是将其排除在外,而在调用方更高层处理故障,例如通过在调用方使用断路器。

备注

如果一个应用的所有实例都处于未就绪状态,则 type=ClusterIPtype=NodePort 的 Kubernetes Service 不会接受任何传入连接。由于根本没有建立连接,因此不会返回 HTTP 错误响应(如 503 等)。对于 type=LoadBalancer 的服务,是否接受连接则取决于具体的云提供商。如果服务配置了显式的 ingress,其响应方式也取决于具体实现——ingress 服务本身需要决定如何处理来自下游的“连接被拒绝”情况。在负载均衡器和 ingress 的情况下,返回 HTTP 503 是非常可能的。

此外,如果应用程序使用了 Kubernetes autoscaling,它可能会根据其 autoscaler 配置的不同,对从负载均衡器中移除的应用程序做出不同的反应。

应用生命周期与探针状态

Kubernetes 探针支持的一个重要方面是其与应用程序生命周期的一致性。AvailabilityState(即应用程序的内存中内部状态)与实际的探针(用于暴露该状态)之间存在显著差异。根据应用程序生命周期的不同阶段,探针可能不可用。

Spring Boot 在启动和关闭期间会发布应用程序事件,探针可以监听这些事件并暴露 AvailabilityState 信息。

下表展示了不同阶段的 AvailabilityState 以及 HTTP 连接器的状态。

当一个 Spring Boot 应用程序启动时:

启动阶段LivenessStateReadinessStateHTTP 服务器说明
StartingBROKENREFUSING_TRAFFIC未启动Kubernetes 检查 "liveness" 探针,如果耗时过长则重启应用。
StartedCORRECTREFUSING_TRAFFIC拒绝请求应用上下文已刷新。应用执行启动任务,但尚未接收流量。
ReadyCORRECTACCEPTING_TRAFFIC接受请求启动任务已完成。应用正在接收流量。

当一个 Spring Boot 应用程序关闭时:

关闭阶段存活状态(Liveness State)就绪状态(Readiness State)HTTP 服务器说明
运行中CORRECTACCEPTING_TRAFFIC接受请求已请求关闭。
优雅关闭CORRECTREFUSING_TRAFFIC新请求被拒绝如果启用,优雅关闭会处理正在进行的请求
关闭完成N/AN/A服务器已关闭应用上下文已关闭,应用已停止。
提示

有关 Kubernetes 部署的更多信息,请参阅 Kubernetes 容器生命周期

应用程序信息

应用程序信息会暴露从你的 ApplicationContext 中定义的所有 InfoContributor Bean 收集到的各种信息。Spring Boot 内置了多个自动配置的 InfoContributor Bean,你也可以编写自己的实现。

自动配置的 InfoContributors

在适当的情况下,Spring 会自动配置以下 InfoContributor bean:

IDNameDescriptionPrerequisites
buildBuildInfoContributor暴露构建信息。一个 META-INF/build-info.properties 资源。
envEnvironmentInfoContributor暴露 Environment 中所有以 info. 开头的属性。无。
gitGitInfoContributor暴露 Git 信息。一个 git.properties 资源。
javaJavaInfoContributor暴露 Java 运行时信息。无。
osOsInfoContributor暴露操作系统信息。无。
processProcessInfoContributor暴露进程信息。无。
sslSslInfoContributor暴露 SSL 证书信息。已配置 SSL Bundle

单个贡献者是否启用由其 management.info.<id>.enabled 属性控制。不同的贡献者对此属性有不同的默认值,这取决于它们的先决条件以及所暴露信息的性质。

由于没有前提条件表明应启用它们,envjavaosprocess 这几个 contributor 默认是禁用的。ssl contributor 的前提是已配置了 SSL Bundle,但它默认也是禁用的。每个 contributor 都可以通过将其 management.info.<id>.enabled 属性设置为 true 来启用。

buildgit 信息贡献者默认是启用的。可以通过将其 management.info.<id>.enabled 属性设置为 false 来分别禁用它们。或者,若要禁用所有通常默认启用的贡献者,可将 management.info.defaults.enabled 属性设置为 false

自定义应用程序信息

当启用 env 贡献者时,你可以通过设置 info.* Spring 属性来自定义 info 端点暴露的数据。所有位于 info 键下的 Environment 属性都会自动暴露。例如,你可以在 application.properties 文件中添加以下配置:

info.app.encoding=UTF-8
info.app.java.source=17
info.app.java.target=17
提示

除了硬编码这些值之外,你还可以在构建时展开 info 属性

假设你使用 Maven,可以将前面的示例重写如下:

info.app.encoding=@project.build.sourceEncoding@
info.app.java.source=@java.version@
info.app.java.target=@java.version@

Git Commit 信息

info 端点的另一个有用特性是,它能够发布项目构建时其 git 源代码仓库的状态信息。如果存在一个 GitProperties Bean,你可以使用 info 端点来暴露这些属性。

提示

如果在 classpath 根目录下存在 git.properties 文件,则会自动配置一个 GitProperties Bean。更多详情请参见 生成 Git 信息

默认情况下,该端点会暴露 git.branchgit.commit.idgit.commit.time 属性(如果存在)。如果你不希望在端点响应中包含这些属性中的任意一个,则需要将它们从 git.properties 文件中排除。如果你想显示完整的 Git 信息(即 git.properties 的全部内容),请使用 management.info.git.mode 属性,如下所示:

management.info.git.mode=full

要完全禁用 info 端点中的 git 提交信息,请将 management.info.git.enabled 属性设置为 false,如下所示:

management.info.git.enabled=false

构建信息

如果一个 BuildProperties Bean 可用,info 端点还可以发布有关你的构建的信息。当 classpath 中存在 META-INF/build-info.properties 文件时,就会发生这种情况。

提示

Maven 和 Gradle 插件都可以生成该文件。更多详情请参见 生成构建信息

Java 信息

info 端点会发布有关你的 Java 运行时环境的信息,更多详情请参见 JavaInfo

OS Information

info 端点发布有关你的操作系统的相关信息,更多详情请参见 OsInfo

Process Information

info 端点发布有关您的进程的信息,更多详情请参见 ProcessInfo

SSL 信息

info 端点会发布有关您的 SSL 证书的信息(这些证书是通过 SSL Bundles 配置的),更多详情请参见 SslInfo。该端点复用了 SslHealthIndicator 的 “警告阈值” 属性(management.health.ssl.certificate-validity-warning-threshold)。如果某个 SSL 证书将在该阈值定义的时间范围内失效,那么在端点响应的 SSL 部分 中,其状态将为 WILL_EXPIRE_SOON

编写自定义 InfoContributor

要提供自定义应用程序信息,你可以注册实现 InfoContributor 接口的 Spring Bean。

以下示例提供了一个包含单个值的 example 条目:

import java.util.Collections;

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

@Component
public class MyInfoContributor implements InfoContributor {

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

}

如果你访问 info 端点,你应该会看到一个包含以下额外条目的响应:

{
"example": {
"key" : "value"
}
}

软件物料清单(SBOM)

sbom 端点公开了 Software Bill of Materials(软件物料清单)。CycloneDX SBOM 可以自动检测,但也可以手动配置其他格式。

sbom 执行器端点将暴露一个名为 "application" 的 SBOM,用于描述你的应用程序的内容。

提示

若要在项目构建时自动生成 CycloneDX SBOM,请参阅 生成 CycloneDX SBOM 章节。

其他 SBOM 格式

如果你想以不同的格式发布 SBOM,可以使用一些配置属性。

配置属性 management.endpoint.sbom.application.location 用于设置应用程序 SBOM 的位置。例如,将其设置为 classpath:sbom.json 将使用 classpath 中 /sbom.json 资源的内容。

CycloneDX、SPDX 和 Syft 格式的 SBOM 的媒体类型会自动检测。要覆盖自动检测的媒体类型,请使用配置属性 management.endpoint.sbom.application.media-type

附加的 SBOM

执行器端点可以处理多个 SBOM。要添加 SBOM,请使用配置属性 management.endpoint.sbom.additional,如下例所示:

management.endpoint.sbom.additional.system.location=optional:file:/system.spdx.json
management.endpoint.sbom.additional.system.media-type=application/spdx+json

这将添加一个名为 "system" 的 SBOM,它存储在 /system.spdx.json 中。可以使用 optional: 前缀来防止在文件不存在时导致启动失败。