端点
Actuator 端点允许您监控和与应用程序交互。
Spring Boot 包含多个内置端点,并允许您添加自定义端点。
例如,health
端点提供基本的应用程序健康信息。
您可以 控制对每个端点的访问 并 通过 HTTP 或 JMX 暴露它们(使其可远程访问)。
当端点的访问被允许且暴露时,视为可用。
内置端点仅在可用时才会自动配置。
大多数应用程序选择通过 HTTP 暴露端点,其中端点的 ID 和 /actuator
前缀映射到 URL。
例如,默认情况下,health
端点映射到 /actuator/health
。
要了解更多关于 Actuator 端点及其请求和响应格式的信息,请参阅 API 文档。 |
以下是可用的技术无关端点:
ID | Description |
---|---|
|
暴露当前应用程序的审计事件信息。
需要一个 |
|
显示应用程序中所有 Spring bean 的完整列表。 |
|
暴露可用的缓存。 |
|
显示配置和自动配置类上评估的条件以及它们匹配或不匹配的原因。 |
|
显示所有 |
|
暴露 Spring 的 |
|
显示已应用的 Flyway 数据库迁移。
需要一个或多个 |
|
显示应用程序健康信息。 |
|
显示 HTTP 交换信息(默认情况下为最近 100 次 HTTP 请求-响应交换)。
需要一个 |
|
显示任意应用程序信息。 |
|
显示 Spring Integration 图。
需要依赖 |
|
显示和修改应用程序中日志记录器的配置。 |
|
显示已应用的 Liquibase 数据库迁移。
需要一个或多个 |
|
显示当前应用程序的 “metrics” 信息,以诊断应用程序记录的指标。 |
|
显示所有 |
|
显示 Quartz Scheduler 作业的信息。 受 敏感信息清理 限制。 |
|
显示应用程序中的计划任务。 |
|
允许从 Spring Session 支持的会话存储中检索和删除用户会话。 需要使用 Spring Session 的基于 Servlet 的 Web 应用程序。 |
|
允许应用程序优雅关闭。 仅在使用 jar 打包时有效。 默认禁用。 |
|
显示由 |
|
执行线程转储。 |
如果您的应用程序是 Web 应用程序(Spring MVC、Spring WebFlux 或 Jersey),您可以使用以下额外的端点:
ID | Description |
---|---|
|
返回堆转储文件。
在 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
请求。
暴露端点
默认情况下,只有 health
端点通过 HTTP 和 JMX 暴露。
由于端点可能包含敏感信息,您应谨慎考虑何时暴露它们。
要更改暴露的端点,请使用以下技术特定的 include
和 exclude
属性:
Property | Default |
---|---|
|
|
|
|
|
|
|
|
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。
|
安全性
出于安全考虑,默认情况下只有 /health
端点通过 HTTP 暴露。
您可以使用 management.endpoints.web.exposure.include
属性配置暴露的端点。
在设置 management.endpoints.web.exposure.include 之前,请确保暴露的 Actuator 端点不包含敏感信息,通过防火墙保护,或使用 Spring Security 等方式保护。
|
如果 Spring Security 在类路径中且没有其他 SecurityFilterChain
bean,Spring Boot 自动配置将保护除 /health
外的所有 Actuator 端点。
如果您定义了自定义 SecurityFilterChain
bean,Spring Boot 自动配置将退避,让您完全控制 Actuator 访问规则。
如果您希望为 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 文档。
如果您在防火墙后部署应用程序,您可能希望所有 Actuator 端点无需身份验证即可访问。
您可以通过更改 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()
}
}
在上述两个示例中,配置仅适用于 Actuator 端点。
由于 Spring Boot 的安全配置在存在任何 SecurityFilterChain bean 时完全退避,您需要配置额外的 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
外的值 -
没有应用自定义
SanitizingFunction
bean
可清理端点的 show-values
属性可以配置为以下值之一:
-
never
- 值始终完全清理(替换为******
) -
always
- 值对所有用户显示(只要没有应用SanitizingFunction
bean) -
when-authorized
- 仅对授权用户显示值(只要没有应用SanitizingFunction
bean)
对于 HTTP 端点,如果用户已通过身份验证并具有端点角色属性配置的角色,则视为授权用户。 默认情况下,任何经过身份验证的用户都被视为授权用户。
对于 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。
|
Actuator 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 。
|
实现自定义端点
如果您添加一个使用 @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
}
因为端点是技术无关的,方法签名中只能指定简单类型。
特别是,声明一个具有 name 和 counter 属性的 CustomData 类型的单一参数不受支持。
|
要让输入映射到操作方法的参数,Java 代码实现端点时应使用 -parameters 编译。
对于 Kotlin 代码,请参阅 Spring Framework 参考文档中的 建议。
如果您使用 Spring Boot 的 Gradle 插件或 Maven 和 spring-boot-starter-parent ,这将自动发生。
|
输入类型转换
传递给端点操作方法的参数,如有必要,会自动转换为所需类型。
在调用操作方法之前,通过 JMX 或 HTTP 接收的输入将使用 ApplicationConversionService
实例以及任何使用 @EndpointConverter
限定的 Converter
或 GenericConverter
bean 转换为所需类型。
自定义 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[]
兼容的类型。
Consumes
对于使用请求体的 @WriteOperation
(HTTP POST
),谓词的 consumes
子句为 application/vnd.spring-boot.actuator.v2+json, application/json
。
对于所有其他操作,consumes
子句为空。
Produces
谓词的 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 WebFlux 时,返回 Resource
的操作自动支持范围请求。
使用 Jersey 时不支持范围请求。 |
Web 端点安全性
Web 端点或 Web 特定端点扩展上的操作可以接收当前 Principal
或 SecurityContext
作为方法参数。
前者通常与 @javax.annotation.Nullable
或 @Nullable
结合使用,为经过身份验证和未经过身份验证的用户提供不同的行为。
后者通常用于通过其 isUserInRole(String)
方法执行授权检查。
健康信息
您可以使用健康信息检查运行中应用程序的状态。
它常被监控软件用于在生产系统宕机时发出警报。
health
端点暴露的信息取决于 management.endpoint.health.show-details
和 management.endpoint.health.show-components
属性,可配置为以下值之一:
Name | Description |
---|---|
|
从不显示详细信息。 |
|
仅对授权用户显示详细信息。
可通过 |
|
对所有用户显示详细信息。 |
默认值为 never
。
当用户具有端点的一个或多个角色时,视为授权用户。
如果端点未配置角色(默认情况),所有经过身份验证的用户都被视为授权用户。
您可以使用 management.endpoint.health.roles
属性配置角色。
如果您的应用程序已启用安全保护并希望使用 always ,您的安全配置必须允许经过身份验证和未经过身份验证的用户访问健康端点。
|
健康信息从 HealthContributorRegistry
的内容中收集(默认情况下,是您 ApplicationContext
中定义的所有 HealthContributor
实例)。
Spring Boot 包含多个自动配置的 HealthContributor
bean,您也可以编写自己的。
HealthContributor
可以是 HealthIndicator
或 CompositeHealthContributor
。
HealthIndicator
提供实际的健康信息,包括 Status
。
CompositeHealthContributor
提供其他 HealthContributor
实例的复合。
这些贡献者共同形成一个树形结构,以表示整个系统健康状况。
默认情况下,最终系统健康状况由 StatusAggregator
派生,它根据状态的有序列表对每个 HealthIndicator
的状态进行排序。
排序列表中的第一个状态用作总体健康状态。
如果没有 HealthIndicator
返回 StatusAggregator
已知的状态,则使用 UNKNOWN
状态。
您可以使用 HealthContributorRegistry 在运行时注册和注销健康指示器。
|
自动配置的 HealthIndicator
在适当情况下,Spring Boot 自动配置下表中列出的 HealthIndicator
bean。
您还可以通过配置 management.health.key.enabled
启用或禁用选定的指示器,key
如下表所示:
Key | Name | Description |
---|---|---|
|
检查 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 将发出警告,但仍返回 HTTP 200 以避免中断应用程序。
您可以使用此阈值为即将过期的证书轮换提供足够的提前时间。
|
额外的 HealthIndicator
bean 可用,但默认不启用:
Key | Name | Description |
---|---|---|
|
暴露 “Liveness” 应用程序可用性状态。 |
|
|
暴露 “Readiness” 应用程序可用性状态。 |
编写自定义 HealthIndicator
要提供自定义健康信息,您可以注册实现 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 调用,需要在任何连接超时之前响应。
Spring Boot 将为任何响应时间超过 10 秒的健康指示器记录警告消息。
如果您想配置此阈值,可以使用 management.endpoint.health.logging.slow-indicator-threshold 属性。
|
除了 Spring Boot 预定义的 Status
类型,Health
还可以返回表示新系统状态的自定义 Status
。
在这种情况下,您还需要提供 StatusAggregator
接口的自定义实现,或者使用 management.endpoint.health.status.order
配置属性配置默认实现。
例如,假设您的某个 HealthIndicator
实现中使用了一个代码为 FATAL
的新 Status
。
要配置严重性顺序,请在应用程序属性中添加以下属性:
-
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。
|
下表显示了内置状态的默认状态映射:
Status | Mapping |
---|---|
|
|
|
|
|
默认无映射,因此 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 扩展。
|
自动配置的 ReactiveHealthIndicator
在适当情况下,Spring Boot 自动配置以下 ReactiveHealthIndicator
bean:
Key | Name | Description |
---|---|---|
|
检查 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
如果您需要为组注册自定义 StatusAggregator 或 HttpCodeStatusMapper bean,可以使用 @Qualifier("groupname") 。
|
健康组还可以包含/排除 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 等云环境中很有用,在这些环境中,通常出于安全目的为 Actuator 端点使用单独的管理端口。 单独的端口可能导致不可靠的健康检查,因为即使健康检查成功,主应用程序也可能无法正常工作。 可以通过如下配置为健康组设置额外的路径:
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
接口收集 “Liveness” 和 “Readiness” 信息,并使用这些信息在专用的 健康指示器 中: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> 应设置为 Actuator 端点可用的端口。
它可以是主 Web 服务器端口,或如果设置了 "management.server.port" 属性,则为单独的管理端口。
|
这些健康组仅在应用程序 运行在 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 将 “liveness” 和 “readiness” 探针配置为健康组。 这意味着 健康组功能 都适用于它们。 例如,您可以配置额外的健康指示器:
-
Properties
-
YAML
management.endpoint.health.group.readiness.include=readinessState,customCheck
management:
endpoint:
health:
group:
readiness:
include: "readinessState,customCheck"
默认情况下,Spring Boot 不会在这些组中添加其他健康指示器。
“liveness” 探针不应依赖外部系统的健康检查。 如果应用程序的 存活状态 出现问题,Kubernetes 会通过重启应用程序实例来解决问题。 这意味着如果外部系统(例如数据库、Web API 或外部缓存)失败,Kubernetes 可能会重启所有应用程序实例并导致级联失败。
至于 “readiness” 探针,检查外部系统的选择必须由应用程序开发者谨慎决定。 因此,Spring Boot 不会在 readiness 探针中包含任何额外的健康检查。 如果应用程序实例的 就绪状态 未就绪,Kubernetes 不会将流量路由到该实例。 某些外部系统可能不被应用程序实例共享,在这种情况下可以包含在 readiness 探针中。 其他外部系统可能对应用程序不重要(应用程序可能有断路器和回退),在这种情况下绝对不应包含。 不幸的是,所有应用程序实例共享的外部系统很常见,您需要做出判断:将其包含在 readiness 探针中并在外部服务宕机时预期应用程序停止服务,或者将其排除在外并在更高级别处理失败,例如在调用者中使用断路器。
如果所有应用程序实例都未就绪,type=ClusterIP 或 NodePort 的 Kubernetes Service 不会接受任何传入连接。
没有 HTTP 错误响应(503 等),因为没有连接。
type=LoadBalancer 的服务可能接受也可能不接受连接,具体取决于提供商。
具有明确 入口 的服务也以取决于实现的方式响应——入口服务本身必须决定如何处理来自下游的 “连接拒绝”。
在负载均衡器和入口的情况下,HTTP 503 很常见。
|
此外,如果应用程序使用 Kubernetes 自动扩展,它对应用程序从负载均衡器中移除的反应可能因其自动扩展器配置而异。
应用程序生命周期和探针状态
Kubernetes 探针支持的一个重要方面是其与应用程序生命周期的一致性。
AvailabilityState
(应用程序的内存中内部状态)与实际探针(暴露该状态)之间存在显著差异。
根据应用程序生命周期的阶段,探针可能不可用。
Spring Boot 在启动和关闭期间发布 应用程序事件,探针可以监听这些事件并暴露 AvailabilityState
信息。
下表显示了不同阶段的 AvailabilityState
和 HTTP 连接器的状态。
当 Spring Boot 应用程序启动时:
Startup phase | LivenessState | ReadinessState | HTTP server | Notes |
---|---|---|---|---|
Starting |
|
|
Not started |
Kubernetes 检查 "liveness" 探针,如果耗时过长会重启应用程序。 |
Started |
|
|
Refuses requests |
应用程序上下文已刷新。应用程序执行启动任务,尚未接收流量。 |
Ready |
|
|
Accepts requests |
启动任务已完成。应用程序正在接收流量。 |
当 Spring Boot 应用程序关闭时:
Shutdown phase | Liveness State | Readiness State | HTTP server | Notes |
---|---|---|---|---|
Running |
|
|
Accepts requests |
已请求关闭。 |
Graceful shutdown |
|
|
New requests are rejected |
如果启用,优雅关闭处理正在进行的请求。 |
Shutdown complete |
N/A |
N/A |
Server is shut down |
应用程序上下文已关闭,应用程序已停止。 |
有关 Kubernetes 部署的更多信息,请参阅 Kubernetes 容器生命周期。 |
应用程序信息
应用程序信息暴露从您 ApplicationContext
中定义的所有 InfoContributor
bean 收集的各种信息。
Spring Boot 包含多个自动配置的 InfoContributor
bean,您也可以编写自己的。
自动配置的 InfoContributor
在适当情况下,Spring 自动配置下表中列出的 InfoContributor
bean:
ID | Name | Description | Prerequisites |
---|---|---|---|
|
暴露构建信息。 |
|
|
|
暴露 |
无。 |
|
|
暴露 git 信息。 |
|
|
|
暴露 Java 运行时信息。 |
无。 |
|
|
暴露操作系统信息。 |
无。 |
|
|
暴露进程信息。 |
无。 |
|
|
暴露 SSL 证书信息。 |
配置了 SSL Bundle。 |
各个贡献者的启用由其 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
端点暴露的数据。
Environment
中以 info
为键的所有属性都会自动暴露。
例如,您可以在 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
端点暴露这些属性。
如果类路径根目录下有 git.properties 文件,GitProperties bean 会自动配置。
有关详细信息,请参阅 生成 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
端点还可以发布有关构建的信息。
如果类路径中有 META-INF/build-info.properties
文件,则会发生这种情况。
Maven 和 Gradle 插件都可以生成该文件。 有关详细信息,请参阅 生成构建信息。 |
Java 信息
info
端点发布有关 Java 运行时环境的信息,详情请参阅 JavaInfo
。
操作系统信息
info
端点发布有关操作系统的信息,详情请参阅 OsInfo
。
进程信息
info
端点发布有关进程的信息,详情请参阅 ProcessInfo
。
SSL 信息
info
端点发布有关 SSL 证书(通过 SSL Bundle 配置)的信息,详情请参阅 SslInfo
。此端点重用 SslHealthIndicator
的“警告阈值”属性:如果 SSL 证书将在此阈值定义的时间范围内失效,将触发警告。有关详细信息,请参阅 management.health.ssl.certificate-validity-warning-threshold
属性。
编写自定义 InfoContributor
要提供自定义应用程序信息,您可以注册实现 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)
sbom
端点暴露 软件物料清单。
CycloneDX SBOM 可以自动检测,但也可以手动配置其他格式。
sbom
Actuator 端点将暴露一个名为 "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
Actuator 端点可以处理多个 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:
前缀可用于防止文件不存在时启动失败。