1. 概述
本教程將介紹 Spring Boot 2.3 如何與 Kubernetes 探測器集成,從而提供更流暢的雲原生體驗。
首先,我們將簡要介紹 Kubernetes 探測器。然後,我們將切換到 Spring Boot 2.3 如何支持這些探測器。
2. Kubernetes 探針
當 Kubernetes 用作我們的編排平台時,每個節點上的 kubelet 負責保持該節點中的 Pod 健康。
例如,有時我們的應用程序可能需要一些時間才能接受請求。kubelet 可以確保應用程序僅在準備就緒時接收請求。此外,如果 Pod 的主進程由於任何原因崩潰,kubelet 將重新啓動容器。
為了履行這些職責,Kubernetes 有兩個探針:存活探針和就緒探針。
kubelet 將使用就緒探針來確定應用程序何時準備好接受請求。 換句話説,當 Pod 中的所有容器都已就緒時,Pod 即為就緒。
同樣,kubelet 也可以通過存活探針檢查 Pod 是否仍在運行。 基本上,存活探針幫助 kubelet 知道何時應該重新啓動容器。
3. Actuator 中的活躍狀態和就緒狀態
自 Spring Boot 2.3 版本起,<a href="https://docs.spring.io/spring-boot/api/java/org/springframework/boot/health/application/LivenessStateHealthIndicator.html">LivenessStateHealthIndicator</a> 和 <a href="https://docs.spring.io/spring-boot/api/java/org/springframework/boot/health/application/ReadinessStateHealthIndicator.html">ReadinessStateHealthIndicator</a> 類將暴露應用程序的活躍狀態和就緒狀態。當我們將應用程序部署到 Kubernetes 時,Spring Boot 將自動註冊這些健康指示器。
因此,我們可以使用 /actuator/health/liveness 和 /actuator/health/readiness 端點作為我們的活躍狀態和就緒探測,分別使用。
例如,我們可以將它們添加到我們的 Pod 定義中,以配置活躍狀態探測為 HTTP GET 請求:
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 3
periodSeconds: 3我們通常讓 Spring Boot 決定何時啓動這些探針。但是,如果需要,我們可以在 application.properties 中手動啓用它們。
如果我們在使用 Spring Boot 2.3.0 或 2.3.1 時,可以通過配置屬性啓用上述探針:
management.health.probes.enabled=true然而,由於自 Spring Boot 2.3.2 版本起,該屬性已被棄用,原因是 配置混淆
如果使用 Spring Boot 2.3.2 版本,我們可以使用新的屬性來啓用健康檢查和就緒檢查。
management.endpoint.health.probes.enabled=true
management.health.livenessState.enabled=true
management.health.readinessState.enabled=true3.1. 準備就緒和活躍狀態轉換
Spring Boot 使用兩個枚舉來封裝不同的準備就緒和活躍狀態。對於準備就緒狀態,有一個名為 ReadinessState 的枚舉,具有以下值:
- ACCEPTING_TRAFFIC 狀態表示應用程序已準備好接受流量
- REFUSING_TRAFFIC 狀態表示應用程序目前不願接受任何請求
同樣,LivenessState 枚舉代表應用程序的活躍狀態,具有兩個值:
- CORRECT 值表示應用程序正在運行並且其內部狀態正確
- 另一方面,BROKEN 值表示應用程序正在運行,但存在致命故障
以下是準備就緒和活躍狀態如何根據應用程序生命週期事件在 Spring 中進行轉換:
- 註冊監聽器和初始化器
- 準備 Environment
- 準備 ApplicationContext
- 加載 Bean 定義
- 將活躍狀態更改為 CORRECT
- 調用應用程序和命令行運行器
- 將準備就緒狀態更改為 ACCEPTING_TRAFFIC
一旦應用程序啓動並運行,我們(以及 Spring 自身)可以通過發佈適當的 AvailabilityChangeEvents 來更改這些狀態。
4. 管理應用程序可用性
應用程序組件可以通過注入 <a href="https://docs.spring.io/spring-boot/api/java/org/springframework/boot/availability/ApplicationAvailability.html">ApplicationAvailability</a> 接口來獲取當前的健康狀態和可用性狀態。
@Autowired private ApplicationAvailability applicationAvailability;然後我們可以這樣使用它:
assertThat(applicationAvailability.getLivenessState())
.isEqualTo(LivenessState.CORRECT);
assertThat(applicationAvailability.getReadinessState())
.isEqualTo(ReadinessState.ACCEPTING_TRAFFIC);
assertThat(applicationAvailability.getState(ReadinessState.class))
.isEqualTo(ReadinessState.ACCEPTING_TRAFFIC);4.1. 更新可用狀態
我們可以通過發佈 AvailabilityChangeEvent 事件來更新應用程序狀態:
assertThat(applicationAvailability.getLivenessState())
.isEqualTo(LivenessState.CORRECT);
mockMvc.perform(get("/actuator/health/liveness"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value("UP"));
AvailabilityChangeEvent.publish(context, LivenessState.BROKEN);
assertThat(applicationAvailability.getLivenessState())
.isEqualTo(LivenessState.BROKEN);
mockMvc.perform(get("/actuator/health/liveness"))
.andExpect(status().isServiceUnavailable())
.andExpect(jsonPath("$.status").value("DOWN"));如下所示,在發佈任何事件之前,/actuator/health/liveness 端點將返回以下 JSON 格式的 200 OK 響應:
{
"status": "OK"
}然後在打破活性的狀態後,相同的端點返回以下 JSON 格式的 503 服務不可用響應:
{
"status": "DOWN"
}當我們將狀態切換到 REFUSING_TRAFFIC 時,status 的值將變為 OUT_OF_SERVICE。
assertThat(applicationAvailability.getReadinessState())
.isEqualTo(ReadinessState.ACCEPTING_TRAFFIC);
mockMvc.perform(get("/actuator/health/readiness"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value("UP"));
AvailabilityChangeEvent.publish(context, ReadinessState.REFUSING_TRAFFIC);
assertThat(applicationAvailability.getReadinessState())
.isEqualTo(ReadinessState.REFUSING_TRAFFIC);
mockMvc.perform(get("/actuator/health/readiness"))
.andExpect(status().isServiceUnavailable())
.andExpect(jsonPath("$.status").value("OUT_OF_SERVICE"));4.2. 監聽狀態變更
我們可以註冊事件監聽器,以便在應用程序可用狀態發生變化時收到通知:
@Component
public class LivenessEventListener {
@EventListener
public void onEvent(AvailabilityChangeEvent<LivenessState> event) {
switch (event.getState()) {
case BROKEN:
// notify others
break;
case CORRECT:
// we're back
}
}
}在這裏,我們正在監聽應用程序的活躍狀態變化。
5. 自動配置
在總結之前,讓我們看看 Spring Boot 如何自動配置這些探針在 Kubernetes 部署中的作用。該 AvailabilityProbesAutoConfiguration 類負責在條件滿足時註冊 liveness 和 readiness 探針。
事實上,存在一個特殊的 條件,當滿足以下任一條件時,它會註冊探針:
當應用程序滿足任一這些條件時,自動配置會註冊 LivenessStateHealthIndicator 和 ReadinessStateHealthIndicator 類型的 Bean。
6. 結論
在本文中,我們瞭解到如何利用 Spring Boot 提供兩種健康檢查(health probes)用於 Kubernetes 集成。