|
此版本仍在开发中,尚未被视为稳定版本。如需最新稳定版本,请使用 Spring Boot 4.0.4! |
端点
Actuator 端点允许您监控并与应用程序进行交互。
Spring Boot 包含许多内置端点,并允许您添加自己的端点。
例如,health 端点提供基本的应用程序健康信息。
您可以 控制对每个单独端点的访问,并 通过HTTP或JMX公开它们(使它们可远程访问)。
当允许访问并且已公开时,端点被视为可用。
内置端点仅在可用时自动配置。
大多数应用程序选择通过HTTP公开,其中端点的ID和前缀 /actuator 会被映射到一个URL。
例如,默认情况下,health 端点会被映射到 /actuator/health。
| 了解有关Actuator端点及其请求和响应格式的更多信息,请参阅 API文档。 |
以下与技术无关的端点可用:
| ID | 描述 |
|---|---|
|
公开当前应用程序的审计事件信息。
需要一个 |
|
显示应用程序中所有 Spring Bean 的完整列表。 |
|
公开可用的缓存。 |
|
显示在配置类和自动配置类上评估的条件,以及它们匹配或不匹配的原因。 |
|
显示所有 |
|
公开来自 Spring 的 |
|
显示已应用的任何 Flyway 数据库迁移。
需要一个或多个 |
|
显示应用程序健康信息。 |
|
显示 HTTP 交换信息(默认情况下,显示最近 100 个 HTTP 请求-响应交换)。
需要一个 |
|
显示任意应用程序信息。 |
|
显示 Spring Integration 图。
需要依赖于 |
|
显示并修改应用程序中日志记录器的配置。 |
|
显示已应用的任何 Liquibase 数据库迁移。
需要一个或多个 |
|
显示当前应用程序的“指标”信息,以诊断应用程序已记录的指标。 |
|
显示所有 |
|
显示有关Quartz调度程序作业的信息。 受 清理 的约束。 |
|
显示应用程序中的计划任务。 |
|
允许从基于Spring Session的会话存储中检索和删除用户会话。 需要使用Spring Session的基于Servlet的Web应用程序。 |
|
允许应用程序优雅关闭。 仅在使用 jar 打包时有效。 默认情况下已禁用。 |
|
显示由 启动步骤数据 收集的 |
|
执行线程转储。 |
如果您的应用程序是一个 Web 应用程序(Spring MVC、Spring WebFlux 或 Jersey),您可以使用以下额外的端点:
| ID | 描述 |
|---|---|
|
返回堆转储文件。
在 HotSpot JVM 上,返回 |
|
返回日志文件的内容(如果已设置 |
|
以 Prometheus 服务器可以抓取的格式公开指标。
需要依赖于 |
控制对端点的访问
默认情况下,除了 shutdown 和 heapdump 之外的所有端点的访问都是不受限制的。
要配置对某个端点的允许访问,请使用其 management.endpoint.<id>.access 属性。
以下示例允许对 shutdown 端点进行不受限制的访问:
-
Properties
-
YAML
management.endpoint.shutdown.access=unrestricted
management:
endpoint:
shutdown:
access: unrestricted
如果您希望访问权限采用“选择加入”而非“选择退出”模式,请将 management.endpoints.access.default 属性设置为 none,并使用各个端点的 access 属性重新选择加入。
以下示例允许对 loggers 端点进行只读访问,并拒绝访问所有其他端点:
-
Properties
-
YAML
management.endpoints.access.default=none
management.endpoint.loggers.access=read-only
management:
endpoints:
access:
default: none
endpoint:
loggers:
access: read-only
不可访问的端点会从应用程序上下文中完全移除。
如果只想更改端点所暴露的技术,可以改用 include 和 exclude 属性。 |
限制访问
可以使用 management.endpoints.access.max-permitted 属性来限制整个应用程序范围的端点访问。
此属性优先于默认访问权限或单个端点的访问级别。
将其设置为 none 可使所有端点不可访问。
将其设置为 read-only 以仅允许对端点进行读取访问。
对于 @Endpoint、@JmxEndpoint 和 @WebEndpoint,读取访问权限等同于使用 @ReadOperation 注解的端点方法。
对于 @ControllerEndpoint 和 @RestControllerEndpoint,读取访问权限等同于可以处理 GET 和 HEAD 请求的请求映射。
对于 @ServletEndpoint,读取访问权限等同于 GET 和 HEAD 请求。
暴露端点
默认情况下,仅通过 HTTP 和 JMX 暴露健康检查端点。 由于端点可能包含敏感信息,因此在暴露它们时应仔细考虑。
要更改公开的端点,请使用以下特定于技术的 include 和 exclude 属性:
| 属性 | 默认 |
|---|---|
|
|
|
|
|
|
|
|
include 属性列出已公开的端点的 ID。
exclude 属性列出不应该公开的端点的 ID。
exclude 属性优先于 include 属性。
您可以使用端点 ID 列表同时配置 include 和 exclude 属性。
例如,要仅通过 JMX 公开 health 和 info 端点,请使用以下属性:
-
Properties
-
YAML
management.endpoints.jmx.exposure.include=health,info
management:
endpoints:
jmx:
exposure:
include: "health,info"
* 可用于选择所有端点。
例如,要通过 HTTP 公开除 env 和 beans 端点之外的所有内容,请使用以下属性:
-
Properties
-
YAML
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=env,beans
management:
endpoints:
web:
exposure:
include: "*"
exclude: "env,beans"
* 在 YAML 中具有特殊含义,因此如果您想包含(或排除)所有端点,请务必添加引号。 |
| 如果您的应用程序公开可用,我们强烈建议您同时 保护您的端点。 |
如果您想实现自己的端点暴露策略,可以注册一个 EndpointFilter bean。 |
安全
出于安全考虑,默认情况下仅通过 HTTP 公开 /health 端点。
您可以使用 management.endpoints.web.exposure.include 属性来配置要公开的端点。
在设置 management.endpoints.web.exposure.include 之前,请确保公开的执行器端点不包含敏感信息,并通过将其置于防火墙之后或使用 Spring Security 等方式进行保护。 |
如果 Spring Security 在类路径上,且不存在其他 SecurityFilterChain Bean,则除 /health 之外的所有执行器端点都将由 Spring Boot 自动配置进行保护。
如果您定义了自定义的 SecurityFilterChain Bean,Spring Boot 自动配置将退避,让您完全控制执行器端点的访问规则。
如果您希望为 HTTP 端点配置自定义安全性(例如,仅允许具有特定角色的用户访问它们),Spring Boot 提供了一些便捷的 RequestMatcher 对象,您可以将它们与 Spring Security 结合使用。
典型的 Spring Security 配置可能如下例所示:
-
Java
-
Kotlin
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();
}
}
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.Customizer.withDefaults
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.web.SecurityFilterChain
@Configuration(proxyBeanMethods = false)
class MySecurityConfiguration {
@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http.securityMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests { requests ->
requests.anyRequest().hasRole("ENDPOINT_ADMIN")
}
http.httpBasic(withDefaults())
return http.build()
}
}
前面的示例使用 EndpointRequest.toAnyEndpoint() 来匹配对任何端点的请求,然后确保所有请求都具有 ENDPOINT_ADMIN 角色。
EndpointRequest 上还提供了其他几种匹配器方法。
有关详细信息,请参阅 API 文档。
如果您在防火墙后面部署应用程序,您可能希望所有执行器端点都可以在无需身份验证的情况下访问。
您可以通过更改 management.endpoints.web.exposure.include 属性来实现,如下所示:
-
Properties
-
YAML
management.endpoints.web.exposure.include=*
management:
endpoints:
web:
exposure:
include: "*"
此外,如果存在 Spring Security,则需要添加自定义安全配置,以允许对端点进行未身份验证的访问,如下例所示:
-
Java
-
Kotlin
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();
}
}
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)
class MySecurityConfiguration {
@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http.securityMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests { requests ->
requests.anyRequest().permitAll()
}
return http.build()
}
}
在上述两个示例中,配置仅适用于执行器端点。
由于在存在任何 SecurityFilterChain Bean 时,Spring Boot 的安全配置会完全退避,因此您需要配置一个额外的 SecurityFilterChain Bean,其中包含适用于应用程序其余部分的规则。 |
跨站请求伪造保护
由于 Spring Boot 依赖于 Spring Security 的默认配置,因此 CSRF 保护默认是启用的。
这意味着,在使用默认安全配置时,需要 POST(shutdown 和 loggers 端点)、PUT 或 DELETE 的 actuator 端点会收到 403(禁止访问)错误。
| 我们建议仅在创建由非浏览器客户端使用的服务时,才完全禁用 CSRF 保护。 |
您可以找到有关CSRF保护的更多信息,请参阅 Spring Security参考指南。
配置端点
端点会自动缓存不带任何参数的读取操作的响应。
要配置端点缓存响应的时间,请使用其 cache.time-to-live 属性。
以下示例将 beans 端点缓存的生存时间设置为 10 秒:
-
Properties
-
YAML
management.endpoint.beans.cache.time-to-live=10s
management:
endpoint:
beans:
cache:
time-to-live: "10s"
management.endpoint.<name> 前缀唯一标识正在配置的端点。 |
清理敏感值
由 /env、/configprops 和 /quartz 端点返回的信息可能敏感,因此默认情况下,值始终会被完全清理(替换为 ******)。
只有在以下情况下,才能以未清理的形式查看值:
-
show-values属性已被设置为非never的值 -
没有应用自定义的
SanitizingFunctionBean
show-values 属性可以为可清理的端点配置为以下值之一:
-
never- 值始终会被完全清理(替换为******) -
always- 值对所有用户可见(只要没有应用SanitizingFunctionbean) -
when-authorized- 仅向授权用户显示值(只要没有应用SanitizingFunctionbean)
对于HTTP端点,如果用户已进行身份验证并且具有端点的roles属性中配置的角色,则认为该用户已获得授权。 默认情况下,任何已认证的用户都被视为已获得授权。
对于 JMX 端点,所有用户始终会被授权。
以下示例允许所有具有 admin 角色的用户以原始形式查看来自 /env 端点的值。
未经授权的用户或不具有 admin 角色的用户将仅看到经过清理的值。
-
Properties
-
YAML
management.endpoint.env.show-values=when-authorized
management.endpoint.env.roles=admin
management:
endpoint:
env:
show-values: when-authorized
roles: "admin"
此示例假设未定义任何 SanitizingFunction bean。 |
执行器 Web 端点的超媒体
添加了一个“发现页面”,其中包含指向所有端点的链接。
“发现页面”默认在 /actuator 上可用。
要禁用“发现页面”,请在您的应用程序属性中添加以下属性:
-
Properties
-
YAML
management.endpoints.web.discovery.enabled=false
management:
endpoints:
web:
discovery:
enabled: false
当配置了自定义的管理上下文路径时,“发现页面”会自动从 /actuator 移动到管理上下文的根路径。
例如,如果管理上下文路径是 /management,则可以从 /management 访问发现页面。
当管理上下文路径设置为 / 时,发现页面将被禁用,以防止与其他映射发生冲突的可能性。
CORS 支持
跨域资源共享 (CORS) 是一个 W3C 规范,它允许你以灵活的方式指定哪些跨域请求是被授权的。 如果你使用 Spring MVC 或 Spring WebFlux,可以配置 Actuator 的 web 端点以支持此类情况。
CORS支持默认是禁用的,只有在设置management.endpoints.web.cors.allowed-origins属性后才会启用。
以下配置允许来自example.com域的GET和POST调用:
-
Properties
-
YAML
management.endpoints.web.cors.allowed-origins=https://example.com
management.endpoints.web.cors.allowed-methods=GET,POST
management:
endpoints:
web:
cors:
allowed-origins: "https://example.com"
allowed-methods: "GET,POST"
有关选项的完整列表,请参见 CorsEndpointProperties。 |
JSON
在处理 JSON 时,Jackson 用于序列化和反序列化。
默认情况下,使用一个隔离的 ObjectMapper。
这种隔离意味着它不与应用程序的 ObjectMapper 共享相同的配置,并且不受 spring.jackson.* 属性的影响。
要禁用此行为并配置 Actuator 以使用应用程序的 ObjectMapper,请将 management.endpoints.jackson.isolated-object-mapper 设置为 false。
或者,您可以定义自己的 EndpointObjectMapper bean,该 bean 生成满足您需求的 ObjectMapper。
然后,Actuator 将使用它进行 JSON 处理。
实现自定义端点
如果您添加一个带有 @Bean 注解的 @Endpoint,任何带有 @ReadOperation、@WriteOperation 或 @DeleteOperation 注解的方法都会通过 JMX 自动公开,并且在 Web 应用程序中也会通过 HTTP 公开。
可以通过使用 Jersey、Spring MVC 或 Spring WebFlux 将端点通过 HTTP 公开。
如果同时存在 Jersey 和 Spring MVC,将使用 Spring MVC。
以下示例公开了一个返回自定义对象的读取操作:
-
Java
-
Kotlin
@ReadOperation
public CustomData getData() {
return new CustomData("test", 5);
}
@ReadOperation
fun getData(): CustomData {
return 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 name 和 int counter 个参数的写入操作,如下例所示:
-
Java
-
Kotlin
@WriteOperation
public void updateData(String name, int counter) {
// injects "test" and 42
}
@WriteOperation
fun updateData(name: String?, counter: Int) {
// injects "test" and 42
}
由于端点是技术无关的,只能在方法签名中指定简单类型。
特别是,声明一个带有 CustomData 类型的单个参数,该类型定义了 name 和 counter 属性是不被支持的。 |
为了让输入映射到操作方法的参数,实现端点的Java代码应使用 -parameters 编译。
对于Kotlin代码,请查看Spring Framework参考中的 建议。
如果您使用Spring Boot的Gradle插件,或者使用Maven和 spring-boot-starter-parent,这将自动发生。 |
输入类型转换
传递给端点操作方法的参数,如果需要的话,会自动转换为所需类型。
在调用操作方法之前,通过使用 ApplicationConversionService 的实例以及任何带有 Converter 或 GenericConverter 的 @EndpointConverter bean,将通过 JMX 或 HTTP 接收的输入转换为所需类型。
自定义 Web 端点
对 @Endpoint、@WebEndpoint 或 @EndpointWebExtension 的操作会通过 Jersey、Spring MVC 或 Spring WebFlux 自动通过 HTTP 暴露。
如果 Jersey 和 Spring MVC 都可用,则使用 Spring MVC。
路径
谓词的路径由端点的 ID 和 Web 暴露端点的基础路径决定。
默认基础路径为 /actuator。
例如,ID 为 sessions 的端点在谓词中使用 /actuator/sessions 作为其路径。
您可以通过使用 @Selector 注解操作方法的一个或多个参数来进一步自定义路径。
此类参数将作为路径变量添加到路径谓词中。
当调用端点操作时,变量的值会被传入操作方法。
如果您希望捕获所有剩余的路径元素,可以将 @Selector(Match=ALL_REMAINING) 添加到最后一个参数,并使其类型与 String[] 兼容转换。
消费
对于使用请求体的 @WriteOperation(HTTP POST),谓词的 consumes 子句为 application/vnd.spring-boot.actuator.v2+json, application/json。
对于所有其他操作,consumes 子句为空。
生成
谓词的 produces 子句可以由 @DeleteOperation、@ReadOperation 和 @WriteOperation 注解的 produces 属性确定。
该属性是可选的。
如果未使用该属性,则会自动确定 produces 子句。
Web 端点响应状态
端点操作的默认响应状态取决于操作类型(读取、写入或删除)以及操作返回的内容(如果有)。
如果 @ReadOperation 返回一个值,响应状态将为 200(OK)。
如果它不返回值,响应状态将为 404(Not Found)。
如果 @WriteOperation 或 @DeleteOperation 返回一个值,响应状态将为 200(OK)。
如果它不返回值,响应状态将为 204(No Content)。
如果调用操作时缺少必需参数,或提供的参数无法转换为所需类型,则不会调用操作方法,响应状态将为 400(Bad Request)。
Web 端点范围请求
您可以使用 HTTP 范围请求来请求 HTTP 资源的一部分。
当使用 Spring MVC 或 Spring Web Flux 时,返回 Resource 的操作会自动支持范围请求。
| 使用 Jersey 时不支持范围请求。 |
Web 端点安全
Web 端点或特定于 Web 的端点扩展上的操作可以接收当前的 Principal 或 SecurityContext 作为方法参数。
前者通常与 @javax.annotation.Nullable 或 @Nullable 结合使用,以便为已认证和未认证用户提供不同的行为。
后者通常用于通过调用其 isUserInRole(String) 方法来执行授权检查。
健康信息
您可以使用健康信息来检查正在运行的应用程序的状态。
监控软件通常利用它在生产系统宕机时发出警报。
health 端点公开的信息取决于 management.endpoint.health.show-details 和 management.endpoint.health.show-components 属性,这些属性可以配置为以下值之一:
| 名称 | 描述 |
|---|---|
|
详细信息从不显示。 |
|
详细信息仅对授权用户显示。
可以使用 |
|
详细信息对所有用户可见。 |
默认值为 never。
当用户属于端点的一个或多个角色时,即被视为已授权。
如果端点未配置任何角色(默认情况),则所有经过身份验证的用户均被视为已授权。
您可以使用 management.endpoint.health.roles 属性来配置角色。
如果您已保护应用程序并希望使用 always,则您的安全配置必须允许经过身份验证和未经过身份验证的用户访问健康端点。 |
健康信息是从 HealthContributorRegistry 的内容中收集的(默认情况下,是您的 ApplicationContext 中定义的所有 HealthContributor 实例)。
Spring Boot 包含许多自动配置的 HealthContributor Bean,您也可以编写自己的 Bean。
HealthContributor 可以是 HealthIndicator 或 CompositeHealthContributor。
HealthIndicator 提供实际的健康信息,包括 Status。
CompositeHealthContributor 提供其他 HealthContributor 实例的组合。
综上所述,贡献者形成一个树状结构来表示系统的整体健康状况。
默认情况下,最终的系统健康状况由 StatusAggregator 派生而来,它根据一个有序的状态列表对来自每个 HealthIndicator 的状态进行排序。
排序列表中的第一个状态被用作整体健康状态。
如果没有 HealthIndicator 返回 StatusAggregator 已知的状态,则使用 UNKNOWN 状态。
您可以使用 HealthContributorRegistry 在运行时注册和注销健康指示器。 |
自动配置的 HealthIndicators
在适当的情况下,Spring Boot 会自动配置下表中列出的 HealthIndicator Bean。
您还可以通过配置 management.health.key.enabled 来启用或禁用选定的指标,
使用下表中列出的 key:
| 键 | 名称 | 描述 |
|---|---|---|
|
检查 Cassandra 数据库是否已启动。 |
|
|
检查 Couchbase 集群是否已启动。 |
|
|
检查是否可以获取到与 |
|
|
检查磁盘空间是否不足。 |
|
|
检查 Elasticsearch 集群是否已启动。 |
|
|
检查 Hazelcast 服务器是否已启动。 |
|
|
检查 JMS 代理是否已启动。 |
|
|
检查 LDAP 服务器是否处于运行状态。 |
|
|
检查邮件服务器是否处于运行状态。 |
|
|
检查 Mongo 数据库是否已启动。 |
|
|
检查 Neo4j 数据库是否已启动。 |
|
|
始终响应 |
|
|
检查 Rabbit 服务器是否已启动。 |
|
|
检查 Redis 服务器是否正在运行。 |
|
|
检查 SSL 证书是否正常。 |
您可以通过设置 management.health.defaults.enabled 属性来禁用它们全部。 |
ssl HealthIndicator 有一个名为 management.health.ssl.certificate-validity-warning-threshold 的“警告阈值”属性。
您可以使用此阈值为轮换即将过期的证书预留充足的时间。
如果 SSL 证书将在该阈值定义的期限内失效,HealthIndicator 将在其响应的详细信息部分报告此情况,其中 details.validChains.certificates.[*].validity.status 的值将为 WILL_EXPIRE_SOON。 |
还有额外的 HealthIndicator 个 Bean 可用,但默认未启用:
| 键 | 名称 | 描述 |
|---|---|---|
|
公开“Liveness”应用程序可用性状态。 |
|
|
公开“就绪”应用程序可用性状态。 |
编写自定义 HealthIndicators
要提供自定义健康信息,您可以注册实现 HealthIndicator 接口的 Spring Bean。
您需要提供 health() 方法的实现,并返回一个 Health 响应。
Health 响应应包含状态,并且可以选择包含要显示的其他详细信息。
以下代码展示了一个示例 HealthIndicator 实现:
-
Java
-
Kotlin
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 ...
}
}
import org.springframework.boot.actuate.health.Health
import org.springframework.boot.actuate.health.HealthIndicator
import org.springframework.stereotype.Component
@Component
class MyHealthIndicator : HealthIndicator {
override fun health(): Health {
val errorCode = check()
if (errorCode != 0) {
return Health.down().withDetail("Error Code", errorCode).build()
}
return Health.up().build()
}
private fun check(): Int {
// perform some specific health check
return ...
}
}
给定 HealthIndicator 的标识符是 Bean 的名称,如果存在 HealthIndicator 后缀,则不包含该后缀。
在前面的示例中,健康信息可在名为 my 的条目中找到。 |
健康指标通常通过 HTTP 调用,并且需要在任何连接超时之前响应。
对于响应时间超过 10 秒的任何健康指标,Spring Boot 将记录一条警告消息。
如果要配置此阈值,可以使用 management.endpoint.health.logging.slow-indicator-threshold 属性。 |
除了 Spring Boot 预定义的 Status 类型外,Health 还可以返回一个表示新系统状态的自定义 Status。
在这种情况下,您还需要提供 StatusAggregator 接口的自定义实现,或者必须通过使用 management.endpoint.health.status.order 配置属性来配置默认实现。
例如,假设有一个新的 Status,其代码为 FATAL,正在您的某个 HealthIndicator 实现中使用。
要配置严重性顺序,请将以下属性添加到您的应用程序属性中:
-
Properties
-
YAML
management.endpoint.health.status.order=fatal,down,out-of-service,unknown,up
management:
endpoint:
health:
status:
order: "fatal,down,out-of-service,unknown,up"
响应中的 HTTP 状态码反映了整体健康状态。
默认情况下,OUT_OF_SERVICE 和 DOWN 映射到 503。
任何未映射的健康状态(包括 UP)都映射到 200。
如果您通过 HTTP 访问健康端点,可能还需要注册自定义状态映射。
配置自定义映射会禁用 DOWN 和 OUT_OF_SERVICE 的默认映射。
如果要保留默认映射,必须显式配置它们,以及任何自定义映射。
例如,以下属性将 FATAL 映射到 503(服务不可用),并保留 DOWN 和 OUT_OF_SERVICE 的默认映射:
-
Properties
-
YAML
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
management:
endpoint:
health:
status:
http-mapping:
down: 503
fatal: 503
out-of-service: 503
如果您需要更多控制,可以定义自己的 HttpCodeStatusMapper bean。 |
下表显示了内置状态的默认状态映射:
| 状态 | 映射 |
|---|---|
|
|
|
|
|
默认没有映射,因此 HTTP 状态为 |
|
默认没有映射,因此 HTTP 状态为 |
响应式健康指标
对于响应式应用程序(例如使用 Spring WebFlux 的应用程序),ReactiveHealthContributor 提供了一个用于获取应用程序健康状况的非阻塞契约。
与传统的 HealthContributor 类似,健康信息是从 ReactiveHealthContributorRegistry 的内容中收集的(默认情况下,包括在您的 ApplicationContext 中定义的所有 HealthContributor 和 ReactiveHealthContributor 实例)。
不针对响应式 API 进行检查的常规 HealthContributor 实例将在弹性调度器上执行。
在响应式应用程序中,您应该使用 ReactiveHealthContributorRegistry 在运行时注册和注销健康指示器。
如果您需要注册常规的 HealthContributor,则应使用 ReactiveHealthContributor#adapt 对其进行包装。 |
要从响应式 API 提供自定义健康信息,您可以注册实现 ReactiveHealthIndicator 接口的 Spring Bean。
以下代码展示了一个示例 ReactiveHealthIndicator 实现:
-
Java
-
Kotlin
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 ...
}
}
import org.springframework.boot.actuate.health.Health
import org.springframework.boot.actuate.health.ReactiveHealthIndicator
import org.springframework.stereotype.Component
import reactor.core.publisher.Mono
@Component
class MyReactiveHealthIndicator : ReactiveHealthIndicator {
override fun health(): Mono<Health> {
return doHealthCheck()!!.onErrorResume { exception: Throwable? ->
Mono.just(Health.Builder().down(exception).build())
}
}
private fun doHealthCheck(): Mono<Health>? {
// perform some specific health check
return ...
}
}
要自动处理错误,请考虑扩展自 AbstractReactiveHealthIndicator。 |
自动配置的响应式健康指示器
在适当的情况下,Spring Boot 会自动配置以下 ReactiveHealthIndicator Bean:
| 键 | 名称 | 描述 |
|---|---|---|
|
检查 Cassandra 数据库是否已启动。 |
|
|
检查 Couchbase 集群是否已启动。 |
|
|
检查 Elasticsearch 集群是否已启动。 |
|
|
检查 Mongo 数据库是否已启动。 |
|
|
检查 Neo4j 数据库是否已启动。 |
|
|
检查 Redis 服务器是否正在运行。 |
如有必要,响应式指示器会替换常规指示器。
此外,任何未显式处理的 HealthIndicator 都会自动被包装。 |
健康组
有时,将健康指标组织成可用于不同目的的组是很有用的。
要创建健康指示器组,您可以使用 management.endpoint.health.group.<name> 属性,并指定要 include 或 exclude 的健康指示器 ID 列表。
例如,要创建一个仅包含数据库指示器的组,您可以定义以下内容:
-
Properties
-
YAML
management.endpoint.health.group.custom.include=db
management:
endpoint:
health:
group:
custom:
include: "db"
然后,您可以通过按下 localhost:8080/actuator/health/custom 来检查结果。
同样地,要创建一个从组中排除数据库指标并包含所有其他指标的组,您可以定义以下内容:
-
Properties
-
YAML
management.endpoint.health.group.custom.exclude=db
management:
endpoint:
health:
group:
custom:
exclude: "db"
默认情况下,如果健康组包含或排除了一个不存在的健康指示器,启动将失败。
要禁用此行为,请将 management.endpoint.health.validate-group-membership 设置为 false。
默认情况下,组会继承与系统健康状态相同的 StatusAggregator 和 HttpCodeStatusMapper 设置。
但是,您也可以按组定义这些设置。
如果需要,您还可以覆盖 show-details 和 roles 属性:
-
Properties
-
YAML
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
management:
endpoint:
health:
group:
custom:
show-details: "when-authorized"
roles: "admin"
status:
order: "fatal,up"
http-mapping:
fatal: 500
out-of-service: 500
您可以使用 @Qualifier("groupname") 如果需要注册自定义 StatusAggregator 或 HttpCodeStatusMapper beans 以供组使用。 |
健康组也可以包含/排除一个 CompositeHealthContributor。
您还可以仅包含/排除 CompositeHealthContributor 的某个特定组件。
这可以通过使用组件的完全限定名称来完成,如下所示:
management.endpoint.health.group.custom.include="test/primary"
management.endpoint.health.group.custom.exclude="test/primary/b"
在上面的示例中,custom 组将包含名为 primary 的 HealthContributor,它是复合组件 test 的一部分。
这里,primary 本身是一个复合组件,而名为 b 的 HealthContributor 将从 custom 组中排除。
健康组可以在主端口或管理端口的附加路径上提供。 这在云环境中(如 Kubernetes)非常有用,其中为了安全原因,通常会使用单独的管理端口来访问执行器端点。 使用单独的端口可能导致不可靠的健康检查,因为即使健康检查成功,主应用程序可能也无法正常工作。 可以通过以下方式将健康组配置为附加路径:
management.endpoint.health.group.live.additional-path="server:/healthz"
这将使 live 健康组在主服务器端口上的 /healthz 处可用。
前缀是必需的,且必须为 server:(代表主服务器端口)或 management:(代表管理端口,如果已配置)。
路径必须是单个路径段。
数据源健康检查
DataSource 健康指示器显示标准数据源和路由数据源 Bean 的健康状况。
路由数据源的健康状况包括其每个目标数据源的健康状况。
在健康端点的响应中,路由数据源的每个目标都使用其路由键进行命名。
如果您不希望在该指示器的输出中包含路由数据源,请将 management.health.db.ignore-routing-data-sources 设置为 true。
Kubernetes 探针
在Kubernetes上部署的应用程序可以通过容器探针提供有关其内部状态的信息。 根据您的Kubernetes配置,kubelet会调用这些探针并根据结果进行响应。
默认情况下,Spring Boot 管理您的 应用程序可用性 状态。
如果在 Kubernetes 环境中部署,actuator 会从 ApplicationAvailability 接口收集“存活状态”和“就绪状态”信息,并将这些信息用于专用的 健康指标: LivenessStateHealthIndicator 和 ReadinessStateHealthIndicator。
这些指标显示在全局健康端点 ("/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> 应设置为执行器端点可用的端口。
如果已设置 "management.server.port" 属性,它可以是主 Web 服务器端口,也可以是单独的管理端口。 |
这些健康组仅在应用程序运行在 Kubernetes 环境中时自动启用。
您可以通过使用 management.endpoint.health.probes.enabled 配置属性在任何环境中启用它们。
如果应用程序的启动时间超过配置的就绪周期,Kubernetes 会提到 "startupProbe" 作为可能的解决方案。
一般来说,这里不需要 "startupProbe",因为 "readinessProbe" 会在所有启动任务完成之前失败。
这意味着您的应用程序在准备好之前不会接收流量。
但是,如果您的应用程序需要很长时间才能启动,请考虑使用 "startupProbe" 以确保 Kubernetes 在应用程序启动过程中不会终止您的应用程序。
参见描述 探针在应用程序生命周期中的行为 的部分。 |
如果您的 Actuator 端点部署在单独的管理上下文中,则这些端点不会使用与主应用程序相同的 Web 基础设施(端口、连接池、框架组件)。
在这种情况下,即使主应用程序无法正常工作(例如,它无法接受新连接),探针检查也可能成功。
因此,最好在主服务器端口上提供 liveness 和 readiness 健康组。
这可以通过设置以下属性来实现:
management.endpoint.health.probes.add-additional-paths=true
这将使 liveness 组在主服务器端口的 /livez 处可用,以及使 readiness 组在 /readyz 处可用。
可以通过每个组上的 additional-path 属性自定义路径,详细信息请参见 健康组。
使用 Kubernetes 探针检查外部状态
Actuator 将“存活”和“就绪”探针配置为健康组。 这意味着它们可以使用所有 健康组功能。 例如,您可以配置其他健康指标:
-
Properties
-
YAML
management.endpoint.health.group.readiness.include=readinessState,customCheck
management:
endpoint:
health:
group:
readiness:
include: "readinessState,customCheck"
默认情况下,Spring Boot 不会向这些组添加其他健康指示器。
“活性”探测不应依赖外部系统的健康检查。 如果 应用程序的活性状态 出现问题,Kubernetes 会尝试通过重启应用程序实例来解决该问题。 这意味着如果外部系统(如数据库、Web API 或外部缓存)出现故障,Kubernetes 可能会重启所有应用程序实例并导致级联故障。
关于“就绪”探针,“检查外部系统”的选择必须由应用程序开发人员谨慎决定。 因此,Spring Boot 不会在就绪探针中包含任何额外的健康检查。 如果 应用程序实例的就绪状态 为未就绪,Kubernetes 不会将流量路由到该实例。 某些外部系统可能不是应用程序实例共享的,在这种情况下,它们可以包含在就绪探针中。 其他外部系统可能对应用程序来说并不是必需的(应用程序可能有断路器和备用方案),在这种情况下,它们肯定不应该被包含在内。 不幸的是,所有应用程序实例共享的外部系统很常见,你必须做出判断:将其包含在就绪探针中,并在外部服务不可用时预期应用程序被移出服务,或者将其排除在外,并在堆栈的更高层次处理故障,可能通过调用方使用断路器。
如果应用程序的所有实例都未就绪,一个 Kubernetes 服务带有 type=ClusterIP 或 NodePort 不会接受任何传入连接。
没有 HTTP 错误响应(如 503 等),因为没有连接建立。
带有 type=LoadBalancer 的服务可能会或可能不会接受连接,这取决于提供商。
具有显式 入口 的服务也会以一种依赖于实现的方式进行响应 — 入口服务本身必须决定如何处理下游的“连接被拒绝”情况。
在负载均衡器和入口的情况下,HTTP 503 很可能发生。 |
此外,如果应用程序使用 Kubernetes 自动扩展,它对将应用程序移出负载均衡器的反应可能会有所不同,具体取决于其自动扩展程序的配置。
应用程序生命周期和探针状态
Kubernetes 探针支持的一个重要方面是其与应用程序生命周期的一致性。
AvailabilityState(即应用程序的内存内部状态)与实际探针(暴露该状态)之间存在显著差异。
根据应用程序生命周期的阶段,探针可能不可用。
Spring Boot 在启动和关闭期间发布 应用程序事件,
并且探针可以监听这些事件并公开 AvailabilityState 信息。
下表显示了 AvailabilityState 以及 HTTP 连接器在不同阶段的状态。
当 Spring Boot 应用程序启动时:
| 启动阶段 | LivenessState | ReadinessState | HTTP 服务器 | 注意事项 |
|---|---|---|---|---|
启动 |
|
|
尚未开始 |
Kubernetes 会检查“存活”探针,如果耗时过长,则重启应用程序。 |
已启动 |
|
|
拒绝请求 |
应用程序上下文已刷新。应用程序正在执行启动任务,尚未接收流量。 |
就绪 |
|
|
接受请求 |
启动任务已完成。应用程序正在接收流量。 |
当 Spring Boot 应用程序关闭时:
| 关闭阶段 | 存活状态 | 就绪状态 | HTTP 服务器 | 注意事项 |
|---|---|---|---|---|
运行 |
|
|
接受请求 |
已请求关闭。 |
优雅停机 |
|
|
新请求被拒绝 |
如果启用,将优雅地关闭正在处理的请求。 HTTP探测器也会停止接受流量,因此外部无法立即获取可用性状态。 |
关闭完成 |
N/A |
N/A |
服务器已关闭 |
应用上下文已关闭,应用程序已停止。 |
请参阅 Kubernetes 容器生命周期 以了解有关 Kubernetes 部署的更多信息。
特别是,它描述了如何使用 preStop 钩子在 Kubernetes 终止您的应用程序之前,给您的应用程序时间进行优雅关闭。 |
应用信息
应用程序信息展示了从您在 ApplicationContext 中定义的所有 InfoContributor bean 收集的各类信息。
Spring Boot 包含多个自动配置的 InfoContributor bean,您也可以编写自己的。
自动配置的 InfoContributors
在适当的情况下,Spring 会自动配置以下 InfoContributor Bean:
| ID | 名称 | 描述 | 前提条件 |
|---|---|---|---|
|
公开构建信息。 |
A |
|
|
公开 |
None. |
|
|
公开 Git 信息。 |
A |
|
|
公开 Java 运行时信息。 |
None. |
|
|
公开操作系统信息。 |
None. |
|
|
公开进程信息。 |
None. |
|
|
公开 SSL 证书信息。 |
一个 SSL 套件 已配置。 |
是否启用单个贡献者由其 management.info.<id>.enabled 属性控制。
不同的贡献者对此属性有不同的默认值,这取决于它们的前提条件以及所公开信息的性质。
由于没有指示应启用它们的前置条件,env、java、os 和 process 贡献者默认处于禁用状态。ssl 贡献者有一个前置条件,即需要配置 SSL Bundle,但它默认也是禁用的。
可以通过将各自的 management.info.<id>.enabled 属性设置为 true 来启用它们。
默认情况下,build 和 git 信息贡献者是启用的。
可以通过将各自的 management.info.<id>.enabled 属性设置为 false 来禁用它们。
或者,要禁用所有通常默认启用的贡献者,请将 management.info.defaults.enabled 属性设置为 false。
自定义应用程序信息
当启用 env 贡献者时,您可以通过设置 info.* Spring 属性来自定义由 info 端点公开的数据。
info 键下的所有 Environment 属性都会自动公开。
例如,您可以将以下设置添加到您的 application.properties 文件中:
-
Properties
-
YAML
info.app.encoding=UTF-8
info.app.java.source=17
info.app.java.target=17
info:
app:
encoding: "UTF-8"
java:
source: "17"
target: "17"
|
而不是硬编码这些值,你也可以在构建时扩展信息属性。 假设您使用 Maven,您可以将前面的示例重写如下:
|
Git 提交信息
info 端点的另一个有用功能是,它能够在项目构建时发布有关 git 源代码仓库状态的信息。
如果存在 GitProperties Bean,您可以使用 info 端点来暴露这些属性。
一个 GitProperties bean 如果在类路径的根目录下有 git.properties 文件,则会自动配置。
有关详细信息,请参阅 生成 Git 信息。 |
默认情况下,如果存在,端点会暴露 git.branch、git.commit.id 和 git.commit.time 属性。
如果您不希望端点响应中包含这些属性中的任何一个,则需要将它们从 git.properties 文件中排除。
如果您希望显示完整的 git 信息(即 git.properties 的完整内容),请使用 management.info.git.mode 属性,如下所示:
-
Properties
-
YAML
management.info.git.mode=full
management:
info:
git:
mode: "full"
要完全禁用来自 info 端点的 git 提交信息,请将 management.info.git.enabled 属性设置为 false,如下所示:
-
Properties
-
YAML
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。
操作系统信息
info 端点发布有关您的操作系统的信息,请参阅 OsInfo 了解更多详情。
进程信息
info 端点发布有关您的进程的信息,详见 ProcessInfo。
SSL 信息
info 端点发布有关您的 SSL 证书(通过 SSL Bundles 配置)的信息,详见 SslInfo。此端点复用 SslHealthIndicator 的“警告阈值”属性(management.health.ssl.certificate-validity-warning-threshold)。如果 SSL 证书将在该阈值定义的时间跨度内失效,其状态在端点响应的 SSL 部分 中将显示为 WILL_EXPIRE_SOON。
编写自定义 InfoContributors
要提供自定义应用程序信息,您可以注册实现 InfoContributor 接口的 Spring bean。
以下示例贡献了一个具有单个值的 example 条目:
-
Java
-
Kotlin
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"));
}
}
import org.springframework.boot.actuate.info.Info
import org.springframework.boot.actuate.info.InfoContributor
import org.springframework.stereotype.Component
import java.util.Collections
@Component
class MyInfoContributor : InfoContributor {
override fun contribute(builder: Info.Builder) {
builder.withDetail("example", Collections.singletonMap("key", "value"))
}
}
如果您访问 info 端点,您应该会看到一个包含以下附加条目的响应:
{
"example": {
"key" : "value"
}
}
软件物料清单 (SBOM)
The sbom endpoint exposes the 软件物料清单.
CycloneDX SBOMs 可以自动检测,但也可以手动配置其他格式。
sbom 执行器端点将公开一个名为“application”的SBOM,它描述了你的应用程序的内容。
| 要在项目构建时自动生成CycloneDX SBOM,请参阅 生成CycloneDX SBOM 部分。 |
其他 SBOM 格式
如果您希望以其他格式发布 SBOM,可以使用一些配置属性。
配置属性 management.endpoint.sbom.application.location 设置应用程序 SBOM 的位置。
例如,将其设置为 classpath:sbom.json 将使用类路径上 /sbom.json 资源的内容。
CycloneDX、SPDX 和 Syft 格式的 SBOM 媒体类型会被自动检测。
要覆盖自动检测的媒体类型,请使用配置属性 management.endpoint.sbom.application.media-type。
其他 SBOM
执行器端点可以处理多个 SBOM。
要添加 SBOM,请使用配置属性 management.endpoint.sbom.additional,如下例所示:
-
Properties
-
YAML
management.endpoint.sbom.additional.system.location=optional:file:/system.spdx.json
management.endpoint.sbom.additional.system.media-type=application/spdx+json
management:
endpoint:
sbom:
additional:
system:
location: "optional:file:/system.spdx.json"
media-type: "application/spdx+json"
这将添加一个名为“system”的SBOM,它存储在 /system.spdx.json 中。
如果文件不存在,可以使用 optional: 前缀来防止启动失败。