端点

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

您可以启用或禁用每个单独的端点,并通过 HTTP 或 JMX 公开它们(使其远程可访问)。当端点同时启用和公开时,则认为该端点可用。内置端点仅在其可用时才会自动配置。大多数应用程序选择通过 HTTP 公开端点,其中端点的 ID 和前缀/actuator映射到一个 URL。例如,默认情况下,health端点映射到/actuator/health

要了解有关执行器端点及其请求和响应格式的更多信息,请参阅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 集成图。需要依赖于spring-integration-core

loggers

显示和修改应用程序中日志记录器的配置。

liquibase

显示已应用的任何 Liquibase 数据库迁移。需要一个或多个Liquibase bean。

metrics

显示当前应用程序的“指标”信息。

mappings

显示所有@RequestMapping路径的汇总列表。

quartz

显示有关 Quartz 调度程序作业的信息。受清理影响。

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属性)。支持使用 HTTPRange标头来检索日志文件内容的一部分。

prometheus

以 Prometheus 服务器可以抓取的格式公开指标。需要依赖于micrometer-registry-prometheus

启用端点

默认情况下,除shutdown之外的所有端点都已启用。要配置端点的启用,请使用其management.endpoint.<id>.enabled属性。以下示例启用了shutdown端点

  • 属性

  • YAML

management.endpoint.shutdown.enabled=true
management:
  endpoint:
    shutdown:
      enabled: true

如果您希望端点启用采用选择加入而不是选择退出,请将management.endpoints.enabled-by-default属性设置为false,并使用各个端点的enabled属性重新选择加入。以下示例启用info端点并禁用所有其他端点

  • 属性

  • YAML

management.endpoints.enabled-by-default=false
management.endpoint.info.enabled=true
management:
  endpoints:
    enabled-by-default: false
  endpoint:
    info:
      enabled: true
禁用的端点将完全从应用程序上下文中移除。如果您只想更改公开端点的技术,请改用includeexclude属性

公开端点

默认情况下,只有 health 端点通过 HTTP 和 JMX 公开。由于端点可能包含敏感信息,因此您应仔细考虑何时公开它们。

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

属性 默认值

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端点,请使用以下属性

  • 属性

  • YAML

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

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

  • 属性

  • 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之前,请确保公开的执行器不包含敏感信息,通过将其置于防火墙之后来保护它们,或者通过类似 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属性来实现此目的,如下所示

  • 属性

  • 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()
	}

}
在以上两个示例中,配置仅适用于执行器端点。由于 Spring Boot 的安全配置在存在任何SecurityFilterChain bean 时完全回退,因此您需要使用适用于应用程序其余部分的规则配置附加的SecurityFilterChain bean。

跨站点请求伪造 (CSRF) 保护

由于 Spring Boot 依赖于 Spring Security 的默认值,因此 CSRF 保护默认情况下处于启用状态。这意味着当使用默认安全配置时,需要POST(shutdown 和 loggers 端点)、PUTDELETE的执行器端点会收到 403(禁止)错误。

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

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

配置端点

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

  • 属性

  • 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角色的用户将只看到经过清理的值。

  • 属性

  • 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访问。

要禁用“发现页面”,请将以下属性添加到您的应用程序属性中

  • 属性

  • 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调用

  • 属性

  • 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

实现自定义端点

如果您添加了一个用@Endpoint注释的@Bean,则用@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@org.springframework.lang.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 代码应使用-java-parameters编译。如果您使用 Spring Boot 的 Gradle 插件,或者如果您使用 Maven 和spring-boot-starter-parent,则会自动发生这种情况。

输入类型转换

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

自定义 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 方法由操作类型确定,如下表所示

操作 HTTP 方法

@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@WriteOperation注释的produces属性确定。该属性是可选的。如果未使用它,则会自动确定produces子句。

如果操作方法返回voidVoid,则produces子句为空。如果操作方法返回org.springframework.core.io.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 范围请求来请求 HTTP 资源的一部分。当使用 Spring MVC 或 Spring Web Flux 时,返回org.springframework.core.io.Resource的操作会自动支持范围请求。

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

Web 端点安全

Web 端点或 Web 特定端点扩展上的操作可以接收当前java.security.Principalorg.springframework.boot.actuate.endpoint.SecurityContext作为方法参数。前者通常与@Nullable结合使用,为已认证和未认证的用户提供不同的行为。后者通常用于使用其isUserInRole(String)方法执行授权检查。

健康信息

您可以使用健康信息来检查正在运行的应用程序的状态。监控软件经常使用它来在生产系统宕机时提醒某人。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 包含许多自动配置的HealthContributors,您也可以编写自己的HealthContributors

HealthContributor可以是HealthIndicatorCompositeHealthContributorHealthIndicator提供实际的健康信息,包括StatusCompositeHealthContributor提供其他HealthContributors的组合。总而言之,贡献者形成树状结构以表示整体系统健康状况。

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

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

自动配置的HealthIndicators

在适当的情况下,Spring Boot 会自动配置下表中列出的HealthIndicators。您也可以通过配置management.health.key.enabled来启用或禁用选定的指标,其中key列在下表中。

名称 描述

cassandra

CassandraDriverHealthIndicator

检查 Cassandra 数据库是否启动。

couchbase

CouchbaseHealthIndicator

检查 Couchbase 集群是否启动。

db

DataSourceHealthIndicator

检查是否可以获得与DataSource的连接。

diskspace

DiskSpaceHealthIndicator

检查磁盘空间是否不足。

elasticsearch

ElasticsearchRestClientHealthIndicator

检查 Elasticsearch 集群是否启动。

hazelcast

HazelcastHealthIndicator

检查 Hazelcast 服务器是否启动。

influxdb

InfluxDbHealthIndicator

检查 InfluxDB 服务器是否启动。

jms

JmsHealthIndicator

检查 JMS 代理是否启动。

ldap

LdapHealthIndicator

检查 LDAP 服务器是否启动。

mail

MailHealthIndicator

检查邮件服务器是否启动。

mongo

MongoHealthIndicator

检查 Mongo 数据库是否启动。

neo4j

Neo4jHealthIndicator

检查 Neo4j 数据库是否启动。

ping

PingHealthIndicator

始终返回UP

rabbit

RabbitHealthIndicator

检查 Rabbit 服务器是否启动。

redis

RedisHealthIndicator

检查 Redis 服务器是否启动。

您可以通过设置management.health.defaults.enabled属性来禁用所有这些指标。

还有其他HealthIndicators可用,但默认情况下未启用。

名称 描述

livenessstate

LivenessStateHealthIndicator

公开“Liveness”(存活性)应用程序可用性状态。

readinessstate

ReadinessStateHealthIndicator

公开“Readiness”(就绪性)应用程序可用性状态。

编写自定义 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配置属性来配置默认实现。

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

  • 属性

  • 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的默认映射。如果您想保留默认映射,则必须在任何自定义映射 alongside 旁边显式配置它们。例如,以下属性将FATAL映射到 503(服务不可用)并保留DOWNOUT_OF_SERVICE的默认映射。

  • 属性

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

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

状态 映射

DOWN

SERVICE_UNAVAILABLE (503)

OUT_OF_SERVICE

SERVICE_UNAVAILABLE (503)

UP

默认情况下没有映射,因此 HTTP 状态为200

UNKNOWN

默认情况下没有映射,因此 HTTP 状态为200

反应式健康指标

对于反应式应用程序(例如使用 Spring WebFlux 的应用程序),ReactiveHealthContributor提供了一个非阻塞的契约来获取应用程序健康状况。与传统的HealthContributor类似,健康信息是从ReactiveHealthContributorRegistry的内容中收集的(默认情况下,所有在您的ApplicationContext中定义的HealthContributorReactiveHealthContributor实例)。不检查反应式 API 的常规HealthContributors在弹性调度程序上执行。

在反应式应用程序中,您应该使用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扩展。

自动配置的 ReactiveHealthIndicators

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

名称 描述

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 列表。例如,要创建一个仅包含数据库指标的组,您可以定义以下内容:

  • 属性

  • YAML

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

然后,您可以通过访问localhost:8080/actuator/health/custom来检查结果。

类似地,要创建一个从组中排除数据库指标并包含所有其他指标的组,您可以定义以下内容:

  • 属性

  • 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属性。

  • 属性

  • 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 等云环境中非常有用,在这些环境中,出于安全目的,为执行器端点使用单独的管理端口非常常见。拥有单独的端口可能会导致健康检查不可靠,因为即使健康检查成功,主应用程序也可能无法正常工作。健康组可以配置附加路径如下:

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

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

DataSource 健康

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

Kubernetes 探针

部署在 Kubernetes 上的应用程序可以使用容器探针提供有关其内部状态的信息。根据您的 Kubernetes 配置,kubelet 会调用这些探针并对结果做出反应。

默认情况下,Spring Boot 管理您的应用程序可用性状态。如果部署在 Kubernetes 环境中,执行器会从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>应设置为执行器端点可用的端口。如果已设置"management.server.port"属性,则它可能是主 Web 服务器端口或单独的管理端口。

只有当应用程序在 Kubernetes 环境中运行时,才会自动启用这些健康组。您可以使用management.endpoint.health.probes.enabled配置属性在任何环境中启用它们。

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

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

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

这将使liveness组在主服务器端口上的/livez处可用,使readiness组在/readyz处可用。路径可以使用每个组上的additional-path属性进行自定义,详情请参见健康组

使用 Kubernetes 探针检查外部状态

执行器将“liveness”和“readiness”探针配置为健康组。这意味着所有健康组功能都可用于它们。例如,您可以配置额外的健康指标。

  • 属性

  • 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 在就绪探针中不包含任何额外的健康检查。如果应用程序实例的就绪状态未就绪,Kubernetes 不会将流量路由到该实例。某些外部系统可能不被应用程序实例共享,在这种情况下,它们可以包含在就绪探针中。其他外部系统可能对应用程序不是必需的(应用程序可能有断路器和回退),在这种情况下,它们绝对不应该包含在内。不幸的是,所有应用程序实例共享的外部系统很常见,您必须做出判断:将其包含在就绪探针中并预期在外部服务关闭时应用程序将被停止服务,或者将其排除在外并处理堆栈上方的故障,也许可以通过在调用方使用断路器。

如果应用程序的所有实例均未就绪,则type=ClusterIPNodePort的 Kubernetes 服务不接受任何传入连接。没有 HTTP 错误响应(503 等),因为没有连接。具有type=LoadBalancer的服务可能会或可能不会接受连接,具体取决于提供商。具有显式入口的服务的响应方式也取决于实现——入口服务本身必须决定如何处理下游的“连接被拒绝”。对于负载均衡器和入口,HTTP 503 非常有可能。

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

应用程序生命周期和探针状态

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

Spring Boot 在启动和关闭期间发布应用程序事件,探针可以监听此类事件并公开AvailabilityState信息。

下表显示了不同阶段的AvailabilityState和 HTTP 连接器的状态。

当 Spring Boot 应用程序启动时

启动阶段 LivenessState ReadinessState HTTP 服务器 备注

启动中

BROKEN

REFUSING_TRAFFIC

未启动

Kubernetes 检查“liveness”探针,如果花费时间过长则重新启动应用程序。

已启动

CORRECT

REFUSING_TRAFFIC

拒绝请求

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

就绪

CORRECT

ACCEPTING_TRAFFIC

接受请求

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

当 Spring Boot 应用程序关闭时

关闭阶段 Liveness 状态 Readiness 状态 HTTP 服务器 备注

运行中

CORRECT

ACCEPTING_TRAFFIC

接受请求

已请求关闭。

优雅关闭

CORRECT

REFUSING_TRAFFIC

拒绝新的请求

如果启用,优雅关闭会处理进行中的请求

关闭完成

N/A

N/A

服务器已关闭

应用程序上下文已关闭,应用程序已关闭。

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

应用程序信息

应用程序信息公开从ApplicationContext中定义的所有InfoContributor bean 收集的各种信息。Spring Boot 包含许多自动配置的InfoContributor bean,您可以编写自己的 bean。

自动配置的 InfoContributors

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

ID 名称 描述 前提条件

build

BuildInfoContributor

公开构建信息。

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

env

EnvironmentInfoContributor

公开Environment中名称以info.开头的任何属性。

无。

git

GitInfoContributor

公开 git 信息。

一个git.properties资源。

java

JavaInfoContributor

公开 Java 运行时信息。

无。

os

OsInfoContributor

公开操作系统信息。

无。

process

ProcessInfoContributor

公开进程信息。

无。

各个贡献者是否启用由其management.info.<id>.enabled属性控制。不同的贡献者对此属性具有不同的默认值,具体取决于它们的前提条件以及它们公开的信息的性质。

由于没有前提条件表明它们应该启用,因此envjavaosprocess贡献者默认情况下是禁用的。可以通过将其management.info.<id>.enabled属性设置为true来启用每个贡献者。

buildgit信息贡献者默认情况下是启用的。可以通过将其management.info.<id>.enabled属性设置为false来禁用每个贡献者。或者,要禁用通常默认启用的每个贡献者,请将management.info.defaults.enabled属性设置为false

自定义应用程序信息

启用env贡献者后,您可以通过设置info.* Spring 属性来自定义info端点公开的数据。info键下的所有Environment属性都会自动公开。例如,您可以将以下设置添加到您的application.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,您可以将前面的示例改写如下

  • 属性

  • YAML

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属性,如下所示

  • 属性

  • YAML

management.info.git.mode=full
management:
  info:
    git:
      mode: "full"

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

  • 属性

  • 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

编写自定义 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)

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

sbom执行器端点将公开一个名为“application”的 SBOM,该 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,如本例所示

  • 属性

  • 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:前缀防止启动失败。