端點
Actuator 端點讓您監控並與您的應用程式互動。Spring Boot 包含許多內建端點,並讓您新增自己的端點。例如,health
端點提供基本的應用程式健康狀態資訊。
您可以啟用或停用每個個別端點,並透過 HTTP 或 JMX 公開它們(使其可遠端存取)。當端點同時啟用和公開時,才被視為可用。內建端點僅在可用時才會自動組態。大多數應用程式選擇透過 HTTP 公開,其中端點的 ID 和 /actuator
前綴會映射到 URL。例如,預設情況下,health
端點會映射到 /actuator/health
。
若要深入瞭解 Actuator 的端點及其請求和回應格式,請參閱API 文件。 |
以下是與技術無關的可用端點
ID | 描述 |
---|---|
|
公開目前應用程式的稽核事件資訊。需要 |
|
顯示應用程式中所有 Spring bean 的完整列表。 |
|
公開可用的快取。 |
|
顯示在組態和自動組態類別上評估的條件,以及它們符合或不符合的原因。 |
|
顯示所有 |
|
公開來自 Spring 的 |
|
顯示已套用的任何 Flyway 資料庫遷移。需要一個或多個 |
|
顯示應用程式健康狀態資訊。 |
|
顯示 HTTP 交換資訊(預設為最近 100 次 HTTP 請求-回應交換)。需要 |
|
顯示任意應用程式資訊。 |
|
顯示 Spring Integration 圖形。需要依賴 |
|
顯示和修改應用程式中記錄器的組態。 |
|
顯示已套用的任何 Liquibase 資料庫遷移。需要一個或多個 |
|
顯示目前應用程式的「指標」資訊。 |
|
顯示所有 |
|
顯示關於 Quartz 排程器工作的資訊。需經過清理。 |
|
顯示應用程式中排程的任務。 |
|
允許從 Spring Session 支援的工作階段儲存區檢索和刪除使用者工作階段。需要使用 Spring Session 的基於 servlet 的網路應用程式。 |
|
讓應用程式優雅關閉。僅在使用 jar 封裝時有效。預設為停用。 |
|
顯示由 |
|
執行執行緒傾印。 |
如果您的應用程式是網路應用程式(Spring MVC、Spring WebFlux 或 Jersey),您可以使用以下其他端點
ID | 描述 |
---|---|
|
傳回堆積傾印檔案。在 HotSpot JVM 上,會傳回 |
|
傳回記錄檔的內容(如果已設定 |
|
以 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
已停用的端點會完全從應用程式上下文中移除。如果您只想變更公開端點的技術,請改用include 和 exclude 屬性。 |
公開端點
預設情況下,只有 health 端點透過 HTTP 和 JMX 公開。由於端點可能包含敏感資訊,因此您應仔細考慮何時公開它們。
若要變更要公開哪些端點,請使用以下特定技術的 include
和 exclude
屬性
屬性 | 預設值 |
---|---|
|
|
|
|
|
|
|
|
include
屬性列出要公開的端點 ID。exclude
屬性列出不應公開的端點 ID。exclude
屬性的優先順序高於 include
屬性。您可以將 include
和 exclude
屬性都組態為端點 ID 的列表。
例如,若要僅透過 JMX 公開 health
和 info
端點,請使用以下屬性
-
屬性
-
YAML
management.endpoints.jmx.exposure.include=health,info
management:
endpoints:
jmx:
exposure:
include: "health,info"
*
可以用於選取所有端點。例如,若要透過 HTTP 公開所有內容,但 env
和 beans
端點除外,請使用以下屬性
-
屬性
-
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 端點)、PUT
或 DELETE
的 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
網域的 GET
和 POST
呼叫
-
屬性
-
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 name
和 int counter
參數的寫入操作,如下列範例所示
-
Java
-
Kotlin
@WriteOperation
public void updateData(String name, int counter) {
// injects "test" and 42
}
@WriteOperation
fun updateData(name: String?, counter: Int) {
// injects "test" and 42
}
由於端點與技術無關,因此只能在方法簽章中指定簡單類型。特別是,宣告具有定義 name 和 counter 屬性的 CustomData 類型的單個參數不受支援。 |
為了讓輸入映射到操作方法參數,實作端點的 Java 程式碼應使用 -parameters 編譯,而實作端點的 Kotlin 程式碼應使用 -java-parameters 編譯。如果您使用 Spring Boot 的 Gradle 外掛程式,或者您使用 Maven 和 spring-boot-starter-parent ,則會自動發生這種情況。 |
自訂 Web 端點
@Endpoint
、@WebEndpoint
或 @EndpointWebExtension
上的操作會使用 Jersey、Spring MVC 或 Spring WebFlux 自動透過 HTTP 公開。如果 Jersey 和 Spring MVC 都可用,則會使用 Spring MVC。
路徑
謂詞的路徑由端點的 ID 和 Web 公開端點的基本路徑決定。預設基本路徑為 /actuator
。例如,ID 為 sessions
的端點在謂詞中使用 /actuator/sessions
作為其路徑。
您可以透過使用 @Selector
註解操作方法的一個或多個參數來進一步自訂路徑。此類參數會作為路徑變數新增至路徑謂詞。當調用端點操作時,變數的值會傳遞到操作方法中。如果您想要捕獲所有剩餘路徑元素,您可以將 @Selector(Match=ALL_REMAINING)
新增到最後一個參數,並使其成為與 String[]
轉換相容的類型。
HTTP 方法
謂詞的 HTTP 方法由操作類型決定,如下表所示
操作 | HTTP 方法 |
---|---|
|
|
|
|
|
|
Consumes
對於使用請求正文的 @WriteOperation
(HTTP POST
),謂詞的 consumes
子句為 application/vnd.spring-boot.actuator.v2+json, application/json
。對於所有其他操作,consumes
子句為空。
Produces
謂詞的 produces
子句可以由 @DeleteOperation
、@ReadOperation
和 @WriteOperation
註解的 produces
屬性決定。該屬性是選用的。如果未使用它,則會自動決定 produces
子句。
如果操作方法傳回 void
或 Void
,則 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)。
健康狀態資訊
您可以使用健康狀態資訊來檢查正在執行的應用程式的狀態。監控軟體通常使用它來在生產系統當機時提醒人員。health
端點公開的資訊取決於 management.endpoint.health.show-details
和 management.endpoint.health.show-components
屬性,這些屬性可以使用以下值之一進行組態
名稱 | 描述 |
---|---|
|
永遠不顯示詳細資訊。 |
|
詳細資訊僅顯示給已授權的使用者。可以使用 |
|
詳細資訊顯示給所有使用者。 |
預設值為 never
。當使用者屬於端點的一個或多個角色時,該使用者被視為已授權。如果端點沒有組態角色(預設值),則所有已驗證的使用者都被視為已授權。您可以使用 management.endpoint.health.roles
屬性組態角色。
如果您已保護您的應用程式安全,並希望使用 always ,則您的安全性組態必須允許已驗證和未驗證的使用者存取健康狀態端點。 |
健康資訊是從 HealthContributorRegistry
的內容中收集而來(預設情況下,所有在您的 ApplicationContext
中定義的 HealthContributor
實例)。Spring Boot 包含許多自動配置的 HealthContributors
,您也可以編寫自己的。
HealthContributor
可以是 HealthIndicator
或 CompositeHealthContributor
。HealthIndicator
提供實際的健康資訊,包括 Status
(狀態)。CompositeHealthContributor
提供其他 HealthContributor
的組合。總而言之,貢獻者形成樹狀結構,以表示整體系統健康狀況。
預設情況下,最終系統健康狀況由 StatusAggregator
衍生而來,它會根據狀態的排序列表對每個 HealthIndicator
的狀態進行排序。排序列表中的第一個狀態用作整體健康狀態。如果沒有 HealthIndicator
返回 StatusAggregator
已知的狀態,則會使用 UNKNOWN
狀態。
您可以使用 HealthContributorRegistry 在運行時註冊和取消註冊健康指示器。 |
自動配置的 HealthIndicators
在適當的情況下,Spring Boot 會自動配置下表中列出的 HealthIndicators
。您還可以通過配置 management.health.key.enabled
來啟用或禁用選定的指示器,其中 key
列在下表中
鍵 | 名稱 | 描述 |
---|---|---|
|
檢查 Cassandra 資料庫是否已啟動。 |
|
|
檢查 Couchbase 集群是否已啟動。 |
|
|
檢查是否可以取得 |
|
|
檢查磁碟空間是否不足。 |
|
|
檢查 Elasticsearch 集群是否已啟動。 |
|
|
檢查 Hazelcast 伺服器是否已啟動。 |
|
|
檢查 InfluxDB 伺服器是否已啟動。 |
|
|
檢查 JMS Broker 是否已啟動。 |
|
|
檢查 LDAP 伺服器是否已啟動。 |
|
|
檢查郵件伺服器是否已啟動。 |
|
|
檢查 Mongo 資料庫是否已啟動。 |
|
|
檢查 Neo4j 資料庫是否已啟動。 |
|
|
總是回應 |
|
|
檢查 Rabbit 伺服器是否已啟動。 |
|
|
檢查 Redis 伺服器是否已啟動。 |
您可以通過設定 management.health.defaults.enabled 屬性來禁用所有這些指示器。 |
還有其他 HealthIndicators
可用,但預設未啟用
鍵 | 名稱 | 描述 |
---|---|---|
|
公開「存活度」應用程式可用性狀態。 |
|
|
公開「就緒度」應用程式可用性狀態。 |
編寫自訂 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_SERVICE
和 DOWN
對應到 503。任何未對應的健康狀態(包括 UP
)都對應到 200。如果您通過 HTTP 訪問健康端點,您可能還想註冊自訂狀態對應。配置自訂對應會禁用 DOWN
和 OUT_OF_SERVICE
的預設對應。如果您想保留預設對應,則必須顯式配置它們,以及任何自訂對應。例如,以下屬性將 FATAL
對應到 503(服務不可用),並保留 DOWN
和 OUT_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。 |
下表顯示了內建狀態的預設狀態對應
狀態 | 對應 |
---|---|
|
|
|
|
|
預設沒有對應,因此 HTTP 狀態為 |
|
預設沒有對應,因此 HTTP 狀態為 |
反應式健康指示器
對於反應式應用程式(例如使用 Spring WebFlux 的應用程式),ReactiveHealthContributor
為取得應用程式健康狀況提供了非阻塞合約。與傳統的 HealthContributor
類似,健康資訊是從 ReactiveHealthContributorRegistry
的內容中收集而來(預設情況下,所有在您的 ApplicationContext
中定義的 HealthContributor
和 ReactiveHealthContributor
實例)。不針對反應式 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 資料庫是否已啟動。 |
|
|
檢查 Couchbase 集群是否已啟動。 |
|
|
檢查 Elasticsearch 集群是否已啟動。 |
|
|
檢查 Mongo 資料庫是否已啟動。 |
|
|
檢查 Neo4j 資料庫是否已啟動。 |
|
|
檢查 Redis 伺服器是否已啟動。 |
如有必要,反應式指示器會取代常規指示器。此外,任何未明確處理的 HealthIndicator 都會自動包裝。 |
健康群組
有時將健康指示器組織成群組很有用,您可以將這些群組用於不同的目的。
要建立健康指示器群組,您可以使用 management.endpoint.health.group.<name>
屬性,並指定要 include
或 exclude
的健康指示器 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
。
預設情況下,群組繼承與系統健康狀況相同的 StatusAggregator
和 HttpCodeStatusMapper
設定。但是,您也可以在每個群組的基礎上定義這些設定。如果需要,您還可以覆寫 show-details
和 roles
屬性
-
屬性
-
YAML
management.endpoint.health.group.custom.show-details=when-authorized
management.endpoint.health.group.custom.roles=admin
management.endpoint.health.group.custom.status.order=fatal,up
management.endpoint.health.group.custom.status.http-mapping.fatal=500
management.endpoint.health.group.custom.status.http-mapping.out-of-service=500
management:
endpoint:
health:
group:
custom:
show-details: "when-authorized"
roles: "admin"
status:
order: "fatal,up"
http-mapping:
fatal: 500
out-of-service: 500
如果您需要註冊自訂 StatusAggregator 或 HttpCodeStatusMapper Bean 以用於該群組,則可以使用 @Qualifier("groupname") 。 |
健康群組還可以包含/排除 CompositeHealthContributor
。您還可以僅包含/排除 CompositeHealthContributor
的特定組件。這可以使用組件的完整限定名稱來完成,如下所示
management.endpoint.health.group.custom.include="test/primary"
management.endpoint.health.group.custom.exclude="test/primary/b"
在上面的範例中,custom
群組將包含名為 primary
的 HealthContributor
,它是複合 test
的組件。在這裡,primary
本身是一個複合組件,名為 b
的 HealthContributor
將從 custom
群組中排除。
健康群組可以在主端口或管理端口上的其他路徑上提供。這在 Kubernetes 等雲端環境中很有用,在這些環境中,為了安全起見,通常使用單獨的管理端口來處理 Actuator 端點。擁有單獨的端口可能會導致不可靠的健康檢查,因為即使健康檢查成功,主應用程式也可能無法正常工作。可以為健康群組配置其他路徑,如下所示
management.endpoint.health.group.live.additional-path="server:/healthz"
這將使 live
健康群組在主伺服器端口上的 /healthz
路徑上可用。前綴是強制性的,並且必須是 server:
(表示主伺服器端口)或 management:
(表示管理端口,如果已配置。)路徑必須是單一路徑段。
Kubernetes 探針
部署在 Kubernetes 上的應用程式可以使用 容器探針 提供有關其內部狀態的資訊。根據 您的 Kubernetes 配置,kubelet 呼叫這些探針並對結果做出反應。
預設情況下,Spring Boot 管理您的 應用程式可用性 狀態。如果部署在 Kubernetes 環境中,Actuator 會從 ApplicationAvailability
介面收集「存活度」和「就緒度」資訊,並在專用的 健康指示器 中使用該資訊:LivenessStateHealthIndicator
和 ReadinessStateHealthIndicator
。這些指示器顯示在全域健康端點 ("/actuator/health"
) 上。它們還通過使用 健康群組 作為單獨的 HTTP 探針公開:"/actuator/health/liveness"
和 "/actuator/health/readiness"
。
然後,您可以使用以下端點資訊配置您的 Kubernetes 基礎架構
livenessProbe:
httpGet:
path: "/actuator/health/liveness"
port: <actuator-port>
failureThreshold: ...
periodSeconds: ...
readinessProbe:
httpGet:
path: "/actuator/health/readiness"
port: <actuator-port>
failureThreshold: ...
periodSeconds: ...
<actuator-port> 應設定為 Actuator 端點可用的端口。它可以是主 Web 伺服器端口,也可以是單獨的管理端口(如果已設定 "management.server.port" 屬性)。 |
只有當應用程式 在 Kubernetes 環境中運行 時,這些健康群組才會自動啟用。您可以通過使用 management.endpoint.health.probes.enabled
配置屬性在任何環境中啟用它們。
如果應用程式的啟動時間比配置的存活期長,Kubernetes 會將 "startupProbe" 視為可能的解決方案。一般來說,這裡不一定需要 "startupProbe" ,因為 "readinessProbe" 在所有啟動任務完成之前都會失敗。這意味著您的應用程式在準備就緒之前不會接收流量。但是,如果您的應用程式啟動時間很長,請考慮使用 "startupProbe" 以確保 Kubernetes 不會在您的應用程式正在啟動過程中終止它。請參閱描述 探針在應用程式生命週期中的行為方式 的章節。 |
如果您的 Actuator 端點部署在單獨的管理上下文中,則端點不使用與主應用程式相同的 Web 基礎架構(端口、連線池、框架組件)。在這種情況下,即使主應用程式無法正常工作(例如,它無法接受新連線),探針檢查也可能成功。因此,最好在主伺服器端口上提供 liveness
和 readiness
健康群組。這可以通過設定以下屬性來完成
management.endpoint.health.probes.add-additional-paths=true
這將使 liveness
群組在主伺服器端口上的 /livez
路徑上可用,readiness
群組在 /readyz
路徑上可用。可以使用每個群組上的 additional-path
屬性自訂路徑,有關詳細資訊,請參閱 健康群組。
使用 Kubernetes 探針檢查外部狀態
Actuator 將「存活度」和「就緒度」探針配置為健康群組。這意味著 健康群組功能 都適用於它們。例如,您可以配置其他健康指示器
-
屬性
-
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=ClusterIP 或 NodePort 的 Kubernetes 服務將不接受任何傳入連線。沒有 HTTP 錯誤回應(503 等),因為沒有連線。type=LoadBalancer 的服務可能會或可能不會接受連線,具體取決於提供者。具有顯式 Ingress 的服務的回應方式也取決於實作 — Ingress 服務本身必須決定如何處理來自下游的「連線被拒絕」。在負載平衡器和 Ingress 的情況下,很可能出現 HTTP 503。 |
此外,如果應用程式使用 Kubernetes 自動縮放,它可能會對應用程式從負載平衡器中移除做出不同的反應,具體取決於其自動縮放器配置。
應用程式生命週期和探針狀態
Kubernetes 探針支援的一個重要方面是它與應用程式生命週期的一致性。AvailabilityState
(應用程式的記憶體內內部狀態)與實際探針(公開該狀態)之間存在顯著差異。根據應用程式生命週期的階段,探針可能不可用。
Spring Boot 在 啟動和關閉期間發布應用程式事件,探針可以監聽此類事件並公開 AvailabilityState
資訊。
下表顯示了不同階段的 AvailabilityState
和 HTTP 連接器的狀態。
當 Spring Boot 應用程式啟動時
啟動階段 | 存活度狀態 | 就緒度狀態 | HTTP 伺服器 | 備註 |
---|---|---|---|---|
正在啟動 |
|
|
未啟動 |
Kubernetes 檢查「存活度」探針,如果時間過長,則重新啟動應用程式。 |
已啟動 |
|
|
拒絕請求 |
應用程式上下文已刷新。應用程式執行啟動任務,但尚未接收流量。 |
就緒 |
|
|
接受請求 |
啟動任務已完成。應用程式正在接收流量。 |
當 Spring Boot 應用程式關閉時
關閉階段 | 存活度狀態 | 就緒度狀態 | HTTP 伺服器 | 備註 |
---|---|---|---|---|
執行中 |
|
|
接受請求 |
已請求關閉。 |
優雅關閉 |
|
|
新請求被拒絕 |
如果啟用,優雅關閉會處理進行中的請求。 |
關閉完成 |
不適用 |
不適用 |
伺服器已關閉 |
應用程式上下文已關閉,應用程式已關閉。 |
有關 Kubernetes 部署的更多資訊,請參閱 Kubernetes 容器生命週期。 |
應用程式資訊
應用程式資訊公開從您的 ApplicationContext
中定義的所有 InfoContributor
Bean 收集的各種資訊。Spring Boot 包含許多自動配置的 InfoContributor
Bean,您可以編寫自己的 Bean。
自動配置的 InfoContributors
在適當的情況下,Spring 會自動配置以下 InfoContributor
Bean
ID | 名稱 | 描述 | 先決條件 |
---|---|---|---|
|
公開建置資訊。 |
|
|
|
公開名稱以 |
無。 |
|
|
公開 Git 資訊。 |
|
|
|
公開 Java 運行時資訊。 |
無。 |
|
|
公開作業系統資訊。 |
無。 |
|
|
公開處理程序資訊。 |
無。 |
是否啟用個別貢獻者由其 management.info.<id>.enabled
屬性控制。不同的貢獻者對此屬性有不同的預設值,具體取決於其先決條件和它們公開的資訊的性質。
由於沒有先決條件指示應啟用它們,因此預設情況下禁用 env
、java
、os
和 process
貢獻者。可以通過將其 management.info.<id>.enabled
屬性設定為 true
來啟用每個貢獻者。
預設情況下啟用 build
和 git
資訊貢獻者。可以通過將其 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,您可以將前面的範例重寫如下
|
Git 提交資訊
info
端點的另一個有用功能是,當專案建置時,它能夠發布有關您的 git
原始碼儲存庫狀態的資訊。如果 GitProperties
Bean 可用,您可以使用 info
端點公開這些屬性。
如果 git.properties 檔案在類別路徑的根目錄中可用,則會自動配置 GitProperties Bean。有關更多詳細資訊,請參閱 產生 Git 資訊。 |
預設情況下,端點會公開 git.branch
、git.commit.id
和 git.commit.time
屬性(如果存在)。如果您不希望端點回應中包含這些屬性中的任何一個,則需要從 git.properties
檔案中排除它們。如果您想顯示完整的 Git 資訊(即 git.properties
的完整內容),請使用 management.info.git.mode
屬性,如下所示
-
屬性
-
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:
前綴可用於防止檔案不存在時啟動失敗。