端点

Actuator 端点允许您监控和与应用程序交互。 Spring Boot 包含多个内置端点,并允许您添加自定义端点。 例如,health 端点提供基本的应用程序健康信息。

您可以 控制对每个端点的访问通过 HTTP 或 JMX 暴露它们(使其可远程访问)。 当端点的访问被允许且暴露时,视为可用。 内置端点仅在可用时才会自动配置。 大多数应用程序选择通过 HTTP 暴露端点,其中端点的 ID 和 /actuator 前缀映射到 URL。 例如,默认情况下,health 端点映射到 /actuator/health

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

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

ID Description

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

显示当前应用程序的 “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 Description

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 端点无限制访问:

  • 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
不可访问的端点将从应用程序上下文中完全移除。 如果您只想更改端点暴露的技术,请改用 includeexclude 属性

限制访问

可以通过 management.endpoints.access.max-permitted 属性限制整个应用程序的端点访问。 此属性优先于默认访问或单个端点的访问级别。 将其设置为 none 将使所有端点不可访问。 将其设置为 read-only 将仅允许对端点的只读访问。

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

暴露端点

默认情况下,只有 health 端点通过 HTTP 和 JMX 暴露。 由于端点可能包含敏感信息,您应谨慎考虑何时暴露它们。

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

Property Default

management.endpoints.jmx.exposure.exclude

management.endpoints.jmx.exposure.include

health

management.endpoints.web.exposure.exclude

management.endpoints.web.exposure.include

health

include 属性列出暴露的端点 ID。 exclude 属性列出不应暴露的端点 ID。 exclude 属性优先于 include 属性。 您可以使用端点 ID 列表配置 includeexclude 属性。

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

  • Properties

  • YAML

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

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

  • 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 保护默认启用。 这意味着需要 POSTshutdownloggers 端点)、PUTDELETE 的 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 域的 GETPOST 调用:

  • 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 nameint 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
	}
因为端点是技术无关的,方法签名中只能指定简单类型。 特别是,声明一个具有 namecounter 属性的 CustomData 类型的单一参数不受支持。
要让输入映射到操作方法的参数,Java 代码实现端点时应使用 -parameters 编译。 对于 Kotlin 代码,请参阅 Spring Framework 参考文档中的 建议。 如果您使用 Spring Boot 的 Gradle 插件或 Maven 和 spring-boot-starter-parent,这将自动发生。

输入类型转换

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

自定义 Web 端点

@Endpoint@WebEndpoint@EndpointWebExtension 上的操作将自动通过 Jersey、Spring MVC 或 Spring WebFlux 通过 HTTP 暴露。 如果 Jersey 和 Spring MVC 都可用,将使用 Spring MVC。

Web 端点请求谓词

为 Web 暴露的端点上的每个操作自动生成一个请求谓词。

路径

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

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

HTTP 方法

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

Operation HTTP method

@ReadOperation

GET

@WriteOperation

POST

@DeleteOperation

DELETE

Consumes

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

Produces

谓词的 produces 子句可由 @DeleteOperation@ReadOperation@WriteOperationproduces 属性确定。 该属性是可选的。 如果未使用,produces 子句将自动确定。

如果操作方法返回 voidVoidproduces 子句为空。 如果操作方法返回 Resourceproduces 子句为 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 范围请求来请求 HTTP 资源的一部分。 当使用 Spring MVC 或 Spring WebFlux 时,返回 Resource 的操作自动支持范围请求。

使用 Jersey 时不支持范围请求。

Web 端点安全性

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

健康信息

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

Name Description

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 在运行时注册和注销健康指示器。

自动配置的 HealthIndicator

在适当情况下,Spring Boot 自动配置下表中列出的 HealthIndicator bean。 您还可以通过配置 management.health.key.enabled 启用或禁用选定的指示器,key 如下表所示:

Key Name Description

cassandra

CassandraDriverHealthIndicator

检查 Cassandra 数据库是否正常运行。

couchbase

CouchbaseHealthIndicator

检查 Couchbase 集群是否正常运行。

db

DataSourceHealthIndicator

检查是否可以获取到 DataSource 的连接。

diskspace

DiskSpaceHealthIndicator

检查磁盘空间是否不足。

elasticsearch

ElasticsearchRestClientHealthIndicator

检查 Elasticsearch 集群是否正常运行。

hazelcast

HazelcastHealthIndicator

检查 Hazelcast 服务器是否正常运行。

jms

JmsHealthIndicator

检查 JMS 代理是否正常运行。

ldap

LdapHealthIndicator

检查 LDAP 服务器是否正常运行。

mail

MailHealthIndicator

检查邮件服务器是否正常运行。

mongo

MongoHealthIndicator

检查 Mongo 数据库是否正常运行。

neo4j

Neo4jHealthIndicator

检查 Neo4j 数据库是否正常运行。

ping

PingHealthIndicator

始终返回 UP

rabbit

RabbitHealthIndicator

检查 Rabbit 服务器是否正常运行。

redis

RedisHealthIndicator

检查 Redis 服务器是否正常运行。

ssl

SslHealthIndicator

检查 SSL 证书是否正常。

您可以通过设置 management.health.defaults.enabled 属性禁用所有指示器。
ssl HealthIndicator 具有名为 management.health.ssl.certificate-validity-warning-threshold 的“警告阈值”属性。 如果 SSL 证书将在此阈值定义的时间范围内失效,HealthIndicator 将发出警告,但仍返回 HTTP 200 以避免中断应用程序。 您可以使用此阈值为即将过期的证书轮换提供足够的提前时间。

额外的 HealthIndicator bean 可用,但默认不启用:

Key Name Description

livenessstate

LivenessStateHealthIndicator

暴露 “Liveness” 应用程序可用性状态。

readinessstate

ReadinessStateHealthIndicator

暴露 “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_SERVICEDOWN 映射到 503。 任何未映射的健康状态,包括 UP,映射到 200。 如果您通过 HTTP 访问健康端点,您可能还想注册自定义状态映射。 配置自定义映射将禁用 DOWNOUT_OF_SERVICE 的默认映射。 如果您想保留默认映射,必须显式配置它们,以及任何自定义映射。 例如,以下属性将 FATAL 映射到 503(服务不可用)并保留 DOWNOUT_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

DOWN

SERVICE_UNAVAILABLE (503)

OUT_OF_SERVICE

SERVICE_UNAVAILABLE (503)

UP

默认无映射,因此 HTTP 状态为 200

UNKNOWN

默认无映射,因此 HTTP 状态为 200

反应式健康指示器

对于反应式应用程序(例如使用 Spring WebFlux 的应用程序),ReactiveHealthContributor 提供了一个非阻塞的合同,用于获取应用程序健康状况。 类似于传统的 HealthContributor,健康信息从 ReactiveHealthContributorRegistry 的内容中收集(默认情况下,是您 ApplicationContext 中定义的所有 HealthContributorReactiveHealthContributor 实例)。 不检查反应式 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

CassandraDriverReactiveHealthIndicator

检查 Cassandra 数据库是否正常运行。

couchbase

CouchbaseReactiveHealthIndicator

检查 Couchbase 集群是否正常运行。

elasticsearch

ElasticsearchReactiveHealthIndicator

检查 Elasticsearch 集群是否正常运行。

mongo

MongoReactiveHealthIndicator

检查 Mongo 数据库是否正常运行。

neo4j

Neo4jReactiveHealthIndicator

检查 Neo4j 数据库是否正常运行。

redis

RedisReactiveHealthIndicator

检查 Redis 服务器是否正常运行。

如有必要,反应式指示器将替换常规指示器。 此外,任何未显式处理的 HealthIndicator 将自动包装。

健康组

有时将健康指示器组织成组用于不同目的很有用。

要创建健康指示器组,您可以使用 management.endpoint.health.group.<name> 属性并指定要 includeexclude 的健康指示器 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

默认情况下,组继承系统健康的相同 StatusAggregatorHttpCodeStatusMapper 设置。 但是,您也可以按组逐个定义这些设置。 如有需要,您还可以覆盖 show-detailsroles 属性:

  • 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
如果您需要为组注册自定义 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,它是复合 test 的一个组件。 在这里,primary 本身是一个复合,名为 bHealthContributor 将从 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” 信息,并使用这些信息在专用的 健康指示器 中: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 配置属性在任何环境中启用它们。

如果应用程序启动时间超过配置的存活期,Kubernetes 会提到 "startupProbe" 作为可能的解决方案。 一般来说,这里不需要 "startupProbe",因为在所有启动任务完成之前,"readinessProbe" 会失败。 这意味着您的应用程序在准备好之前不会接收流量。 但是,如果您的应用程序启动时间较长,请考虑使用 "startupProbe",以确保 Kubernetes 在应用程序启动过程中不会终止它。 有关探针在应用程序生命周期中的行为,请参阅 探针行为 部分。

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

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=ClusterIPNodePort 的 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

BROKEN

REFUSING_TRAFFIC

Not started

Kubernetes 检查 "liveness" 探针,如果耗时过长会重启应用程序。

Started

CORRECT

REFUSING_TRAFFIC

Refuses requests

应用程序上下文已刷新。应用程序执行启动任务,尚未接收流量。

Ready

CORRECT

ACCEPTING_TRAFFIC

Accepts requests

启动任务已完成。应用程序正在接收流量。

当 Spring Boot 应用程序关闭时:

Shutdown phase Liveness State Readiness State HTTP server Notes

Running

CORRECT

ACCEPTING_TRAFFIC

Accepts requests

已请求关闭。

Graceful shutdown

CORRECT

REFUSING_TRAFFIC

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

build

BuildInfoContributor

暴露构建信息。

META-INF/build-info.properties 资源。

env

EnvironmentInfoContributor

暴露 Environment 中以 info. 开头的任何属性。

无。

git

GitInfoContributor

暴露 git 信息。

git.properties 资源。

java

JavaInfoContributor

暴露 Java 运行时信息。

无。

os

OsInfoContributor

暴露操作系统信息。

无。

process

ProcessInfoContributor

暴露进程信息。

无。

ssl

SslInfoContributor

暴露 SSL 证书信息。

配置了 SSL Bundle

各个贡献者的启用由其 management.info.<id>.enabled 属性控制。 不同的贡献者对此属性的默认值不同,取决于其前提条件和暴露信息的性质。

对于没有前提条件表明应启用的 envjavaosprocess 贡献者,默认禁用。ssl 贡献者需要配置 SSL Bundle,但默认禁用。 每个可以通过将其 management.info.<id>.enabled 属性设置为 true 启用。

buildgit 信息贡献者默认启用。 每个可以通过将其 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,可以将上述示例重写如下:

  • Properties

  • YAML

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

Git 提交信息

info 端点的另一个有用功能是能够发布项目构建时 git 源代码存储库的状态信息。 如果 GitProperties bean 可用,您可以使用 info 端点暴露这些属性。

如果类路径根目录下有 git.properties 文件,GitProperties bean 会自动配置。 有关详细信息,请参阅 生成 Git 信息

默认情况下,端点暴露 git.branchgit.commit.idgit.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: 前缀可用于防止文件不存在时启动失败。