端點
Actuator 端點允許您監控並與您的應用進行互動。Spring Boot 包含許多內建端點,並且允許您新增自己的端點。例如,health
端點提供了基本的應用健康資訊。
您可以控制對每個獨立端點的訪問,並透過 HTTP 或 JMX 暴露(使其遠端可訪問)它們。當允許訪問且已暴露時,端點被視為可用。內建端點僅在可用時才會自動配置。大多數應用選擇透過 HTTP 暴露,其中端點的 ID 和字首 /actuator
被對映到一個 URL。例如,預設情況下,health
端點被對映到 /actuator/health
。
要了解更多關於 Actuator 端點及其請求和響應格式的資訊,請參閱 API 文件。 |
以下技術無關的端點可用
ID | 描述 |
---|---|
|
暴露當前應用的審計事件資訊。需要一個 |
|
顯示應用中所有 Spring bean 的完整列表。 |
|
暴露可用的快取。 |
|
顯示在配置和自動配置類上評估的條件,以及它們匹配或不匹配的原因。 |
|
顯示所有 |
|
暴露 Spring 的 |
|
顯示已應用的 Flyway 資料庫遷移。需要一個或多個 |
|
顯示應用健康資訊。 |
|
顯示 HTTP 交換資訊(預設顯示最近的 100 個 HTTP 請求-響應交換)。需要一個 |
|
顯示任意的應用資訊。 |
|
顯示 Spring 整合圖。需要依賴 |
|
顯示並修改應用中日誌記錄器的配置。 |
|
顯示已應用的 Liquibase 資料庫遷移。需要一個或多個 |
|
顯示當前應用的“指標”資訊,用於診斷應用記錄的指標。 |
|
顯示所有 |
|
顯示關於 Quartz 排程器作業的資訊。受清洗約束。 |
|
顯示應用中的計劃任務。 |
|
允許從 Spring Session 支援的會話儲存中檢索和刪除使用者會話。需要使用 Spring Session 的基於 Servlet 的 Web 應用。 |
|
允許應用優雅停機。僅在使用 jar 打包時有效。預設停用。 |
|
顯示由 |
|
執行執行緒轉儲。 |
如果您的應用是 Web 應用(Spring MVC、Spring WebFlux 或 Jersey),您可以使用以下附加端點
ID | 描述 |
---|---|
|
返回一個堆轉儲檔案。在 HotSpot JVM 上,返回 |
|
返回日誌檔案的內容(如果已設定 |
|
以 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
無法訪問的端點將從應用上下文中完全移除。如果您只想更改端點暴露的技術,請改為使用include 和 exclude 屬性。 |
限制訪問
可以使用 management.endpoints.access.max-permitted
屬性來限制應用範圍的端點訪問。此屬性優先於預設訪問或單個端點的訪問級別。將其設定為 none
會使所有端點都無法訪問。將其設定為 read-only
則只允許對端點進行讀取訪問。
對於 @Endpoint
、@JmxEndpoint
和 @WebEndpoint
,讀取訪問等同於使用 @ReadOperation
註解的端點方法。對於 @ControllerEndpoint
和 @RestControllerEndpoint
,讀取訪問等同於可以處理 GET
和 HEAD
請求的請求對映。對於 @ServletEndpoint
,讀取訪問等同於 GET
和 HEAD
請求。
暴露端點
預設情況下,只有 health 端點透過 HTTP 和 JMX 暴露。由於端點可能包含敏感資訊,您應仔細考慮何時暴露它們。
要更改暴露哪些端點,請使用以下特定於技術的 include
和 exclude
屬性
屬性 | 預設值 |
---|---|
|
|
|
|
|
|
|
|
include
屬性列出了要暴露的端點 ID。exclude
屬性列出了不應暴露的端點 ID。exclude
屬性優先於 include
屬性。您可以將 include
和 exclude
屬性配置為端點 ID 列表。
例如,要僅透過 JMX 暴露 health
和 info
端點,請使用以下屬性
-
Properties
-
YAML
management.endpoints.jmx.exposure.include=health,info
management:
endpoints:
jmx:
exposure:
include: "health,info"
*
可用於選擇所有端點。例如,要透過 HTTP 暴露除 env
和 beans
端點之外的所有內容,請使用以下屬性
-
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 端點)、PUT
或 DELETE
的 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
域的 GET
和 POST
呼叫
-
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 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 程式碼,請查閱 Spring Framework 參考文件中的建議。如果您使用 Spring Boot 的 Gradle 外掛或使用 Maven 和 spring-boot-starter-parent ,這將自動發生。 |
輸入型別轉換
必要時,傳遞給端點操作方法的引數會自動轉換為所需型別。在呼叫操作方法之前,透過 JMX 或 HTTP 接收的輸入會使用 ApplicationConversionService
的例項以及任何使用 @EndpointConverter
限定的 Converter
或 GenericConverter
bean 轉換為所需型別。
定製 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[]
相容。
接收(Consumes)
對於使用請求體的 @WriteOperation
(HTTP POST
),謂詞的 consumes
子句是 application/vnd.spring-boot.actuator.v2+json, application/json
。對於所有其他操作,consumes
子句為空。
生成(Produces)
謂詞的 produces
子句可以由 @DeleteOperation
、@ReadOperation
和 @WriteOperation
註解的 produces
屬性決定。該屬性是可選的。如果未使用,produces
子句將自動確定。
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 特定端點擴充套件上的操作可以接收當前的 Principal
或 SecurityContext
作為方法引數。前者通常與 @javax.annotation.Nullable
或 @Nullable
結合使用,以便為已認證和未認證使用者提供不同的行為。後者通常用於使用其 isUserInRole(String)
方法執行授權檢查。
健康資訊
您可以使用健康資訊來檢查正在執行的應用程式的狀態。監控軟體通常使用它來在生產系統發生故障時發出警報。health
端點公開的資訊取決於 management.endpoint.health.show-details
和 management.endpoint.health.show-components
屬性,這些屬性可以配置為以下值之一:
名稱 | 描述 |
---|---|
|
從不顯示詳細資訊。 |
|
僅向授權使用者顯示詳細資訊。可以透過使用 |
|
向所有使用者顯示詳細資訊。 |
預設值是 never
。當用戶屬於端點的一個或多個角色時,被視為已授權。如果端點沒有配置角色(預設),所有已認證使用者都被視為已授權。您可以使用 management.endpoint.health.roles
屬性配置角色。
如果您已保護您的應用程式並希望使用 always ,則您的安全配置必須允許已認證和未認證使用者訪問健康端點。 |
健康資訊從 HealthContributorRegistry
的內容中收集(預設情況下,包括您 ApplicationContext
中定義的所有 HealthContributor
例項)。Spring Boot 包含許多自動配置的 HealthContributor
bean,您也可以編寫自己的。
一個 HealthContributor
可以是 HealthIndicator
或 CompositeHealthContributor
。一個 HealthIndicator
提供實際的健康資訊,包括一個 Status
。一個 CompositeHealthContributor
提供其他 HealthContributor
例項的組合。總的來說,貢獻者形成一個樹狀結構來表示整體系統健康狀況。
預設情況下,最終的系統健康狀況由 StatusAggregator
得出,它根據狀態的有序列表對每個 HealthIndicator
的狀態進行排序。排序列表中的第一個狀態用作總體健康狀態。如果沒有 HealthIndicator
返回 StatusAggregator
已知的狀態,則使用 UNKNOWN
狀態。
您可以使用 HealthContributorRegistry 在執行時註冊和登出健康指標。 |
自動配置的 HealthIndicators
在適當的時候,Spring Boot 會自動配置下表中列出的 HealthIndicator
bean。您還可以透過配置 management.health.key.enabled
(其中 key
列在下表中)來啟用或停用選定的指標:
鍵 | 名稱 | 描述 |
---|---|---|
|
檢查 Cassandra 資料庫是否正常執行。 |
|
|
檢查 Couchbase 叢集是否正常執行。 |
|
|
檢查是否可以獲取到 |
|
|
檢查磁碟空間是否不足。 |
|
|
檢查 Elasticsearch 叢集是否正常執行。 |
|
|
檢查 Hazelcast 伺服器是否正常執行。 |
|
|
檢查 JMS 代理是否正常執行。 |
|
|
檢查 LDAP 伺服器是否正常執行。 |
|
|
檢查郵件伺服器是否正常執行。 |
|
|
檢查 Mongo 資料庫是否正常執行。 |
|
|
檢查 Neo4j 資料庫是否正常執行。 |
|
|
始終響應 |
|
|
檢查 Rabbit 伺服器是否正常執行。 |
|
|
檢查 Redis 伺服器是否正常執行。 |
|
|
檢查 SSL 證書是否正常。 |
您可以透過設定 management.health.defaults.enabled 屬性來停用所有這些指標。 |
ssl HealthIndicator 有一個名為 management.health.ssl.certificate-validity-warning-threshold 的“警告閾值”屬性。如果在該閾值定義的時間範圍內 SSL 證書將失效,則 HealthIndicator 會發出警告,但仍會返回 HTTP 200,以免中斷應用程式。您可以使用此閾值來為輪換即將過期的證書留出足夠的提前期。 |
還有其他 HealthIndicator
bean 可用,但預設不啟用:
鍵 | 名稱 | 描述 |
---|---|---|
|
公開應用程式的“活躍度(Liveness)”可用性狀態。 |
|
|
公開應用程式的“就緒度(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_SERVICE
和 DOWN
對映到 503。任何未對映的健康狀態,包括 UP
,都對映到 200。如果您透過 HTTP 訪問健康端點,您可能還需要註冊自定義狀態對映。配置自定義對映會停用 DOWN
和 OUT_OF_SERVICE
的預設對映。如果您想保留預設對映,必須明確配置它們,以及任何自定義對映。例如,以下屬性將 FATAL
對映到 503(服務不可用),並保留 DOWN
和 OUT_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。 |
下表顯示了內建狀態的預設狀態對映:
狀態 | 對映 |
---|---|
|
|
|
|
|
預設無對映,因此 HTTP 狀態為 |
|
預設無對映,因此 HTTP 狀態為 |
響應式健康指標
對於響應式應用程式(例如使用 Spring WebFlux 的應用程式),ReactiveHealthContributor
提供了獲取應用程式健康的非阻塞契約。與傳統的 HealthContributor
類似,健康資訊從 ReactiveHealthContributorRegistry
的內容中收集(預設情況下,包括您 ApplicationContext
中定義的所有 HealthContributor
和 ReactiveHealthContributor
例項)。未檢查響應式 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 資料庫是否正常執行。 |
|
|
檢查 Couchbase 叢集是否正常執行。 |
|
|
檢查 Elasticsearch 叢集是否正常執行。 |
|
|
檢查 Mongo 資料庫是否正常執行。 |
|
|
檢查 Neo4j 資料庫是否正常執行。 |
|
|
檢查 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
。
預設情況下,健康組繼承與系統健康相同的 StatusAggregator
和 HttpCodeStatusMapper
設定。但是,您也可以按組定義這些設定。如果需要,您還可以覆蓋 show-details
和 roles
屬性:
-
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
如果您需要註冊用於該組的自定義 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:
(表示管理埠,如果已配置)。路徑必須是單個路徑段。
資料來源健康檢查
DataSource
健康指標顯示標準資料來源和路由資料來源 bean 的健康狀況。路由資料來源的健康狀況包括其每個目標資料來源的健康狀況。在健康端點的響應中,路由資料來源的每個目標都使用其路由鍵命名。如果您不想在指標輸出中包含路由資料來源,請將 management.health.db.ignore-routing-data-sources
設定為 true
。
Kubernetes 探針
部署在 Kubernetes 上的應用程式可以透過容器探針提供其內部狀態的資訊。根據您的 Kubernetes 配置,kubelet 會呼叫這些探針並根據結果做出反應。
預設情況下,Spring Boot 管理您的應用程式可用性(Application Availability)狀態。如果部署在 Kubernetes 環境中,Actuator 會從 ApplicationAvailability
介面收集“活躍度(Liveness)”和“就緒度(Readiness)”資訊,並在專用的健康指標中使用這些資訊: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 端點可用的埠。如果已設定 "management.server.port" 屬性,它可能是主 Web 伺服器埠或單獨的管理埠。 |
這些健康組僅在應用程式執行在 Kubernetes 環境中時自動啟用。您可以透過使用 management.endpoint.health.probes.enabled
配置屬性在任何環境中啟用它們。
如果應用程式啟動時間長於配置的活躍度(liveness)週期,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 將“活躍度(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=ClusterIP 或 NodePort 的 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) |
|
|
未啟動 |
Kubernetes 檢查“存活(liveness)”探針,如果耗時過長則重啟應用。 |
已啟動 (Started) |
|
|
拒絕請求 |
應用上下文已重新整理。應用執行啟動任務,尚未接收流量。 |
就緒 (Ready) |
|
|
接受請求 |
啟動任務已完成。應用正在接收流量。 |
Spring Boot 應用關閉時
關閉階段 | 存活狀態 (Liveness State) | 就緒狀態 (Readiness State) | HTTP 伺服器 | 備註 |
---|---|---|---|---|
執行中 |
|
|
接受請求 |
已請求關閉。 |
優雅關機 |
|
|
新請求被拒絕 |
如果啟用,優雅關機處理進行中的請求。 |
關閉完成 |
不適用 |
不適用 |
伺服器已關閉 |
應用上下文已關閉,應用已停止執行。 |
有關 Kubernetes 部署的更多資訊,請參見Kubernetes 容器生命週期。 |
應用資訊
應用資訊暴露了從 ApplicationContext
中定義的所有 InfoContributor
bean 中收集到的各種資訊。Spring Boot 包含許多自動配置的 InfoContributor
bean,你也可以編寫自己的貢獻者。
自動配置的 InfoContributor
在適當的情況下,Spring 會自動配置以下 InfoContributor
bean:
ID | 名稱 | 描述 | 前提條件 |
---|---|---|---|
|
暴露構建資訊。 |
|
|
|
暴露 |
無。 |
|
|
暴露 git 資訊。 |
|
|
|
暴露 Java 執行時資訊。 |
無。 |
|
|
暴露作業系統資訊。 |
無。 |
|
|
暴露程序資訊。 |
無。 |
|
|
暴露 SSL 證書資訊。 |
配置了SSL Bundle。 |
是否啟用單個貢獻者由其 management.info.<id>.enabled
屬性控制。不同的貢獻者對該屬性有不同的預設值,具體取決於其前提條件和所暴露資訊的性質。
由於沒有前提條件表明它們應該被啟用,env
、java
、os
和 process
貢獻者預設是停用的。ssl
貢獻者需要配置SSL Bundle作為前提條件,但預設也是停用的。透過將其 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
檔案中新增以下設定:
-
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,可以將上述示例重寫如下:
|
Git 提交資訊
info
端點的另一個有用功能是它能夠釋出專案構建時 git
原始碼倉庫狀態的資訊。如果 GitProperties
bean 可用,你可以使用 info
端點暴露這些屬性。
如果在 classpath 的根目錄提供了 git.properties 檔案,則會自動配置一個 GitProperties bean。更多詳細資訊請參見生成 Git 資訊。 |
預設情況下,如果存在,端點會暴露 git.branch
、git.commit.id
和 git.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:
字首來防止檔案不存在時啟動失敗。