端點

Actuator 端點允許您監控並與您的應用進行互動。Spring Boot 包含許多內建端點,並且允許您新增自己的端點。例如,health 端點提供了基本的應用健康資訊。

您可以控制對每個獨立端點的訪問,並透過 HTTP 或 JMX 暴露(使其遠端可訪問)它們。當允許訪問且已暴露時,端點被視為可用。內建端點僅在可用時才會自動配置。大多數應用選擇透過 HTTP 暴露,其中端點的 ID 和字首 /actuator 被對映到一個 URL。例如,預設情況下,health 端點被對映到 /actuator/health

要了解更多關於 Actuator 端點及其請求和響應格式的資訊,請參閱 API 文件

以下技術無關的端點可用

ID 描述

auditevents

暴露當前應用的審計事件資訊。需要一個 AuditEventRepository bean。

beans

顯示應用中所有 Spring bean 的完整列表。

caches

暴露可用的快取。

conditions

顯示在配置和自動配置類上評估的條件,以及它們匹配或不匹配的原因。

configprops

顯示所有 @ConfigurationProperties 的彙總列表。受清洗約束。

env

暴露 Spring 的 ConfigurableEnvironment 中的屬性。受清洗約束。

flyway

顯示已應用的 Flyway 資料庫遷移。需要一個或多個 Flyway bean。

health

顯示應用健康資訊。

httpexchanges

顯示 HTTP 交換資訊(預設顯示最近的 100 個 HTTP 請求-響應交換)。需要一個 HttpExchangeRepository bean。

info

顯示任意的應用資訊。

integrationgraph

顯示 Spring 整合圖。需要依賴 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 屬性)。支援使用 HTTP Range 頭部來檢索日誌檔案內容的一部分。

prometheus

以 Prometheus 伺服器可抓取的格式暴露指標。需要依賴 micrometer-registry-prometheus

控制端點訪問

預設情況下,除了 shutdown 外,所有端點的訪問都是不受限制的。要配置允許的端點訪問,請使用其 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 屬性

屬性 預設值

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 屬性。您可以將 includeexclude 屬性配置為端點 ID 列表。

例如,要僅透過 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 等進行保護。

如果在 classpath 中存在 Spring Security 且沒有其他 SecurityFilterChain bean,則除 /health 外的所有 Actuator 都將由 Spring Boot 自動配置保護。如果您定義自定義的 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 端點)、PUTDELETE 的 Actuator 端點在使用預設安全配置時會收到 403(禁止訪問)錯誤。

僅當您正在建立由非瀏覽器客戶端使用的服務時,我們才建議完全停用 CSRF 保護。

您可以在 Spring Security 參考指南中找到有關 CSRF 保護的更多資訊。

配置端點

端點會自動快取不帶任何引數的讀取操作的響應。要配置端點快取響應的時間量,請使用其 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 端點,如果使用者已認證且具有端點 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。

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

實現自定義端點

如果您新增一個使用 @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@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 方法由操作型別決定,如下表所示:

操作 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 子句為空。如果操作方法返回 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 WebFlux 時,返回 Resource 的操作會自動支援範圍請求。

使用 Jersey 時不支援範圍請求。

Web 端點安全性

Web 端點或 Web 特定端點擴充套件上的操作可以接收當前的 PrincipalSecurityContext 作為方法引數。前者通常與 @javax.annotation.Nullable@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 包含許多自動配置的 HealthContributor bean,您也可以編寫自己的。

一個 HealthContributor 可以是 HealthIndicatorCompositeHealthContributor。一個 HealthIndicator 提供實際的健康資訊,包括一個 Status。一個 CompositeHealthContributor 提供其他 HealthContributor 例項的組合。總的來說,貢獻者形成一個樹狀結構來表示整體系統健康狀況。

預設情況下,最終的系統健康狀況由 StatusAggregator 得出,它根據狀態的有序列表對每個 HealthIndicator 的狀態進行排序。排序列表中的第一個狀態用作總體健康狀態。如果沒有 HealthIndicator 返回 StatusAggregator 已知的狀態,則使用 UNKNOWN 狀態。

您可以使用 HealthContributorRegistry 在執行時註冊和登出健康指標。

自動配置的 HealthIndicators

在適當的時候,Spring Boot 會自動配置下表中列出的 HealthIndicator bean。您還可以透過配置 management.health.key.enabled(其中 key 列在下表中)來啟用或停用選定的指標:

名稱 描述

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 可用,但預設不啟用:

名稱 描述

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。要配置嚴重性順序,請在您的應用程式屬性中新增以下屬性:

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

下表顯示了內建狀態的預設狀態對映:

狀態 對映

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

自動配置的 ReactiveHealthIndicators

在適當的時候,Spring Boot 會自動配置以下 ReactiveHealthIndicator bean:

名稱 描述

cassandra

CassandraDriverReactiveHealthIndicator

檢查 Cassandra 資料庫是否正常執行。

couchbase

CouchbaseReactiveHealthIndicator

檢查 Couchbase 叢集是否正常執行。

elasticsearch

ElasticsearchReactiveHealthIndicator

檢查 Elasticsearch 叢集是否正常執行。

mongo

MongoReactiveHealthIndicator

檢查 Mongo 資料庫是否正常執行。

neo4j

Neo4jReactiveHealthIndicator

檢查 Neo4j 資料庫是否正常執行。

redis

RedisReactiveHealthIndicator

檢查 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

預設情況下,健康組繼承與系統健康相同的 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 管理您的應用程式可用性(Application Availability)狀態。如果部署在 Kubernetes 環境中,Actuator 會從 ApplicationAvailability 介面收集“活躍度(Liveness)”和“就緒度(Readiness)”資訊,並在專用的健康指標中使用這些資訊:LivenessStateHealthIndicatorReadinessStateHealthIndicator。這些指標會顯示在全域性健康端點 ("/actuator/health") 上。它們也作為單獨的 HTTP 探針透過健康分組公開:"/actuator/health/liveness""/actuator/health/readiness"

然後,您可以使用以下端點資訊配置您的 Kubernetes 基礎設施:

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

readinessProbe:
  httpGet:
    path: "/actuator/health/readiness"
    port: <actuator-port>
  failureThreshold: ...
  periodSeconds: ...
<actuator-port> 應設定為 Actuator 端點可用的埠。如果已設定 "management.server.port" 屬性,它可能是主 Web 伺服器埠或單獨的管理埠。

這些健康組僅在應用程式執行在 Kubernetes 環境中時自動啟用。您可以透過使用 management.endpoint.health.probes.enabled 配置屬性在任何環境中啟用它們。

如果應用程式啟動時間長於配置的活躍度(liveness)週期,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 不在就緒度探針中包含任何附加的健康檢查。如果應用程式例項的就緒度狀態未準備好,Kubernetes 不會將流量路由到該例項。某些外部系統可能不是由所有應用程式例項共享的,在這種情況下,它們可以包含在就緒度探針中。其他外部系統可能對應用程式不重要(應用程式可能具有斷路器和回退機制),在這種情況下,它們絕對不應包含在內。不幸的是,由所有應用程式例項共享的外部系統很常見,您必須做出判斷:將其包含在就緒度探針中,並在外部服務宕機時預期應用程式將退出服務,或者將其排除,並在堆疊的更高層處理故障,也許可以透過在呼叫方使用斷路器來實現。

如果應用程式的所有例項都處於未就緒狀態,則具有 type=ClusterIPNodePort 的 Kubernetes Service 不會接受任何傳入連線。由於沒有連線,因此不會出現 HTTP 錯誤響應(503 等)。具有 type=LoadBalancer 的 Service 可能會或可能不會接受連線,具體取決於提供商。具有顯式ingress 的 Service 的響應方式也取決於實現——ingress 服務本身必須決定如何處理來自下游的“連線被拒絕”。在負載均衡器和 ingress 的情況下,HTTP 503 的可能性很高。

此外,如果應用程式使用 Kubernetes autoscaling(自動伸縮),它對應用程式退出負載均衡器的反應方式可能會因其自動伸縮配置而異。

應用生命週期和探針狀態

Kubernetes 探針支援的一個重要方面是它與應用生命週期的一致性。在 AvailabilityState(它是應用的記憶體內部狀態)和實際探針(它暴露了該狀態)之間存在顯著差異。根據應用生命週期的階段,探針可能不可用。

Spring Boot 在啟動和關閉期間釋出應用事件,探針可以監聽這些事件並暴露 AvailabilityState 資訊。

下表顯示了不同階段的 AvailabilityState 和 HTTP 聯結器狀態。

Spring Boot 應用啟動時

啟動階段 LivenessState(存活狀態) ReadinessState(就緒狀態) HTTP 伺服器 備註

正在啟動 (Starting)

BROKEN(損壞)

REFUSING_TRAFFIC(拒絕流量)

未啟動

Kubernetes 檢查“存活(liveness)”探針,如果耗時過長則重啟應用。

已啟動 (Started)

CORRECT(正確)

REFUSING_TRAFFIC(拒絕流量)

拒絕請求

應用上下文已重新整理。應用執行啟動任務,尚未接收流量。

就緒 (Ready)

CORRECT(正確)

ACCEPTING_TRAFFIC(接受流量)

接受請求

啟動任務已完成。應用正在接收流量。

Spring Boot 應用關閉時

關閉階段 存活狀態 (Liveness State) 就緒狀態 (Readiness State) HTTP 伺服器 備註

執行中

CORRECT(正確)

ACCEPTING_TRAFFIC(接受流量)

接受請求

已請求關閉。

優雅關機

CORRECT(正確)

REFUSING_TRAFFIC(拒絕流量)

新請求被拒絕

如果啟用,優雅關機處理進行中的請求

關閉完成

不適用

不適用

伺服器已關閉

應用上下文已關閉,應用已停止執行。

有關 Kubernetes 部署的更多資訊,請參見Kubernetes 容器生命週期

應用資訊

應用資訊暴露了從 ApplicationContext 中定義的所有 InfoContributor bean 中收集到的各種資訊。Spring Boot 包含許多自動配置的 InfoContributor bean,你也可以編寫自己的貢獻者。

自動配置的 InfoContributor

在適當的情況下,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

暴露程序資訊。

無。

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 端點暴露的資料。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"

除了硬編碼這些值之外,你還可以在構建時擴充套件 info 屬性

假設你使用 Maven,可以將上述示例重寫如下:

  • Properties

  • YAML

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

Git 提交資訊

info 端點的另一個有用功能是它能夠釋出專案構建時 git 原始碼倉庫狀態的資訊。如果 GitProperties bean 可用,你可以使用 info 端點暴露這些屬性。

如果在 classpath 的根目錄提供了 git.properties 檔案,則會自動配置一個 GitProperties bean。更多詳細資訊請參見生成 Git 資訊

預設情況下,如果存在,端點會暴露 git.branchgit.commit.idgit.commit.time 屬性。如果你不希望響應中包含這些屬性,需要從 git.properties 檔案中排除它們。如果你想顯示完整的 git 資訊(即 git.properties 的完整內容),請使用 management.info.git.mode 屬性,如下所示:

  • 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 的“警告閾值”屬性:如果 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 端點暴露軟體物料清單 (Software Bill of Materials)。可以自動檢測 CycloneDX SBOM,但也可以手動配置其他格式。

然後,sbom actuator 端點將暴露一個名為“application”的 SBOM,它描述了你的應用內容。

要在專案構建時自動生成 CycloneDX SBOM,請參見生成 CycloneDX SBOM 部分。

其他 SBOM 格式

如果你想釋出其他格式的 SBOM,可以使用一些配置屬性。

配置屬性 management.endpoint.sbom.application.location 設定應用 SBOM 的位置。例如,將其設定為 classpath:sbom.json 將使用 classpath 中 /sbom.json 資源的內容。

CycloneDX、SPDX 和 Syft 格式的 SBOM 的媒體型別會自動檢測。要覆蓋自動檢測的媒體型別,請使用配置屬性 management.endpoint.sbom.application.media-type

附加 SBOM

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: 字首來防止檔案不存在時啟動失敗。