端點

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 Integration 圖形。需要依賴 spring-integration-core

loggers

顯示和修改應用程式中記錄器的組態。

liquibase

顯示已套用的任何 Liquibase 資料庫遷移。需要一個或多個 Liquibase bean。

metrics

顯示目前應用程式的「指標」資訊。

mappings

顯示所有 @RequestMapping 路徑的整理列表。

quartz

顯示關於 Quartz 排程器工作的資訊。需經過清理

scheduledtasks

顯示應用程式中排程的任務。

sessions

允許從 Spring Session 支援的工作階段儲存區檢索和刪除使用者工作階段。需要使用 Spring Session 的基於 servlet 的網路應用程式。

shutdown

讓應用程式優雅關閉。僅在使用 jar 封裝時有效。預設為停用。

startup

顯示由 ApplicationStartup 收集的啟動步驟資料。需要使用 BufferingApplicationStartup 組態 SpringApplication

threaddump

執行執行緒傾印。

如果您的應用程式是網路應用程式(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>.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 屬性。您可以將 includeexclude 屬性都組態為端點 ID 的列表。

例如,若要僅透過 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 之前,請確保公開的 Actuator 不包含敏感資訊、透過將它們放在防火牆後方來保護,或透過類似 Spring Security 的機制來保護。

如果 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 屬性來達成此目的,如下所示

  • 屬性

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

  • 屬性

  • 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,則會自動發生這種情況。

輸入類型轉換

傳遞給端點操作方法的參數會在必要時自動轉換為所需的類型。在呼叫操作方法之前,透過 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 子句為空。如果操作方法傳回 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,您也可以編寫自己的。

HealthContributor 可以是 HealthIndicatorCompositeHealthContributorHealthIndicator 提供實際的健康資訊,包括 Status(狀態)。CompositeHealthContributor 提供其他 HealthContributor 的組合。總而言之,貢獻者形成樹狀結構,以表示整體系統健康狀況。

預設情況下,最終系統健康狀況由 StatusAggregator 衍生而來,它會根據狀態的排序列表對每個 HealthIndicator 的狀態進行排序。排序列表中的第一個狀態用作整體健康狀態。如果沒有 HealthIndicator 返回 StatusAggregator 已知的狀態,則會使用 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 Broker 是否已啟動。

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

公開「存活度」應用程式可用性狀態。

readinessstate

ReadinessStateHealthIndicator

公開「就緒度」應用程式可用性狀態。

編寫自訂 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 的預設對應。如果您想保留預設對應,則必須顯式配置它們,以及任何自訂對應。例如,以下屬性將 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 等雲端環境中很有用,在這些環境中,為了安全起見,通常使用單獨的管理端口來處理 Actuator 端點。擁有單獨的端口可能會導致不可靠的健康檢查,因為即使健康檢查成功,主應用程式也可能無法正常工作。可以為健康群組配置其他路徑,如下所示

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 環境中,Actuator 會從 ApplicationAvailability 介面收集「存活度」和「就緒度」資訊,並在專用的 健康指示器 中使用該資訊: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 將「存活度」和「就緒度」探針配置為健康群組。這意味著 健康群組功能 都適用於它們。例如,您可以配置其他健康指示器

  • 屬性

  • YAML

management.endpoint.health.group.readiness.include=readinessState,customCheck
management:
  endpoint:
    health:
      group:
        readiness:
          include: "readinessState,customCheck"

預設情況下,Spring Boot 不會將其他健康指示器添加到這些群組中。

「存活度」探針不應依賴於外部系統的健康檢查。如果應用程式的 存活度狀態 損壞,Kubernetes 會嘗試通過重新啟動應用程式實例來解決該問題。這意味著如果外部系統(例如資料庫、Web API 或外部快取)失敗,Kubernetes 可能會重新啟動所有應用程式實例並造成級聯故障。

至於「就緒度」探針,是否檢查外部系統的選擇必須由應用程式開發人員仔細權衡。因此,Spring Boot 不會在就緒度探針中包含任何其他健康檢查。如果應用程式實例的 就緒度狀態 未就緒,Kubernetes 不會將流量路由到該實例。某些外部系統可能不被應用程式實例共享,在這種情況下,它們可以包含在就緒度探針中。其他外部系統可能對應用程式不是必要的(應用程式可能具有斷路器和後備機制),在這種情況下,它們絕對不應包含在內。不幸的是,所有應用程式實例共享的外部系統很常見,您必須做出判斷:將其包含在就緒度探針中,並預期當外部服務關閉時應用程式將停止服務,或者將其排除在外,並在堆疊的更上層處理故障,也許通過在呼叫者中使用斷路器。

如果應用程式的所有實例都未就緒,則 type=ClusterIPNodePort 的 Kubernetes 服務將不接受任何傳入連線。沒有 HTTP 錯誤回應(503 等),因為沒有連線。type=LoadBalancer 的服務可能會或可能不會接受連線,具體取決於提供者。具有顯式 Ingress 的服務的回應方式也取決於實作 — Ingress 服務本身必須決定如何處理來自下游的「連線被拒絕」。在負載平衡器和 Ingress 的情況下,很可能出現 HTTP 503。

此外,如果應用程式使用 Kubernetes 自動縮放,它可能會對應用程式從負載平衡器中移除做出不同的反應,具體取決於其自動縮放器配置。

應用程式生命週期和探針狀態

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

Spring Boot 在 啟動和關閉期間發布應用程式事件,探針可以監聽此類事件並公開 AvailabilityState 資訊。

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

當 Spring Boot 應用程式啟動時

啟動階段 存活度狀態 就緒度狀態 HTTP 伺服器 備註

正在啟動

BROKEN (損壞)

REFUSING_TRAFFIC (拒絕流量)

未啟動

Kubernetes 檢查「存活度」探針,如果時間過長,則重新啟動應用程式。

已啟動

CORRECT (正確)

REFUSING_TRAFFIC (拒絕流量)

拒絕請求

應用程式上下文已刷新。應用程式執行啟動任務,但尚未接收流量。

就緒

CORRECT (正確)

ACCEPTING_TRAFFIC (接受流量)

接受請求

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

當 Spring Boot 應用程式關閉時

關閉階段 存活度狀態 就緒度狀態 HTTP 伺服器 備註

執行中

CORRECT (正確)

ACCEPTING_TRAFFIC (接受流量)

接受請求

已請求關閉。

優雅關閉

CORRECT (正確)

REFUSING_TRAFFIC (拒絕流量)

新請求被拒絕

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

關閉完成

不適用

不適用

伺服器已關閉

應用程式上下文已關閉,應用程式已關閉。

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

應用程式資訊

應用程式資訊公開從您的 ApplicationContext 中定義的所有 InfoContributor Bean 收集的各種資訊。Spring Boot 包含許多自動配置的 InfoContributor Bean,您可以編寫自己的 Bean。

自動配置的 InfoContributors

在適當的情況下,Spring 會自動配置以下 InfoContributor Bean

ID 名稱 描述 先決條件

build

BuildInfoContributor

公開建置資訊。

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

env

EnvironmentInfoContributor

公開名稱以 info. 開頭的 Environment 中的任何屬性。

無。

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 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,如本範例所示

  • 屬性

  • 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: 前綴可用於防止檔案不存在時啟動失敗。