«1. Обзор
В этом уроке мы увидим, как Spring Boot 2.3 интегрируется с зондами Kubernetes, чтобы создать еще более приятный облачный опыт.
Во-первых, мы начнем с небольшой предыстории зондов Kubernetes. Затем мы переключим передачу и посмотрим, как Spring Boot 2.3 поддерживает эти зонды.
2. Зонды Kubernetes
При использовании Kubernetes в качестве нашей платформы для оркестровки kubelet в каждом узле отвечает за поддержание работоспособности модулей в этом узле.
Например, иногда нашим приложениям может потребоваться некоторое время, прежде чем они смогут принимать запросы. Кублет может сделать так, чтобы приложение получало запросы только тогда, когда оно готово. Кроме того, если по какой-либо причине происходит сбой основного процесса пода, kubelet перезапустит контейнер.
Для выполнения этих обязанностей в Kubernetes есть два зонда: зонды живучести и зонды готовности.
Кублет будет использовать датчик готовности, чтобы определить, когда приложение готово принимать запросы. Точнее, модуль готов, когда готовы все его контейнеры.
Точно так же kubelet может проверить, жив ли под, с помощью зондов живучести. По сути, liveness probe помогает kubelet узнать, когда следует перезапустить контейнер.
Теперь, когда мы знакомы с концепциями, давайте посмотрим, как работает интеграция Spring Boot.
3. Живучесть и готовность в Actuator
Начиная с Spring Boot 2.3, классы LivenessStateHealthIndicator и ReadinessStateHealthIndicator будут отображать состояние живости и готовности приложения. Когда мы развертываем наше приложение в Kubernetes, Spring Boot автоматически регистрирует эти индикаторы работоспособности.
В результате мы можем использовать конечные точки /actuator/health/liveness и /actuator/health/readiness в качестве наших зондов живучести и готовности соответственно.
Например, мы можем добавить их в определение нашего модуля, чтобы настроить проверку живучести как 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=true
3.1. Переходы состояний готовности и жизнеспособности
Spring Boot использует два перечисления для инкапсуляции различных состояний готовности и живучести. Для состояния готовности существует перечисление под названием ReadinessState со следующими значениями:
-
Состояние ACCEPTING_TRAFFIC означает, что приложение готово принимать трафик Состояние REFUSING_TRAFFIC означает, что приложение пока не готово принимать какие-либо запросы
Аналогично, перечисление LivenessState представляет состояние работоспособности приложения двумя значениями:
-
Значение CORRECT означает, что приложение работает и его внутреннее состояние корректно. С другой стороны, значение BROKEN означает, что приложение работает с некоторыми фатальными сбоями ~~ ~ Вот как состояние готовности и жизнеспособности изменяется с точки зрения событий жизненного цикла приложения в Spring:
Как только приложение запущено и работает, мы (и сама Spring) можем изменить эти состояния, опубликовав соответствующие события AvailabilityChangeEvents.
- Registering listeners and initializers
- Preparing the Environment
- Preparing the ApplicationContext
- Loading bean definitions
- Changing the liveness state to CORRECT
- Calling the application and command-line runners
- Changing the readiness state to ACCEPTING_TRAFFIC
4. Управление доступностью приложения
Компоненты приложения могут получать информацию о текущем состоянии готовности и жизнеспособности путем внедрения интерфейса ApplicationAvailability:
Затем мы можем использовать его следующим образом:
@Autowired private ApplicationAvailability applicationAvailability;
4.1. Обновление состояния доступности
assertThat(applicationAvailability.getLivenessState())
.isEqualTo(LivenessState.CORRECT);
assertThat(applicationAvailability.getReadinessState())
.isEqualTo(ReadinessState.ACCEPTING_TRAFFIC);
assertThat(applicationAvailability.getState(ReadinessState.class))
.isEqualTo(ReadinessState.ACCEPTING_TRAFFIC);
Мы также можем обновить состояние приложения, опубликовав событие AvailabilityChangeEvent:
Как показано выше, перед публикацией какого-либо события конечная точка /actuator/health/liveness возвращает ответ 200 OK с следующий JSON:
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"));
«
{
"status": "OK"
}
«Затем, после нарушения состояния жизнеспособности, та же конечная точка возвращает ответ 503 о недоступности службы со следующим JSON:
{
"status": "DOWN"
}
Когда мы переходим в состояние готовности REFUSING_TRAFFIC, значением статуса будет 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 отвечает за условную регистрацию тестов живучести и готовности.
На самом деле там есть специальное условие, которое регистрирует зонды, когда выполняется одно из следующих условий:
-
Kubernetes — среда развертывания. Свойство management.health.probes.enabled имеет значение true ~~ ~ Когда приложение соответствует любому из этих условий, автоконфигурация регистрирует bean-компоненты LivenessStateHealthIndicator и ReadinessStateHealthIndicator.
6. Заключение
В этой статье мы увидели, как мы можем использовать Spring Boot, который предоставляет две проверки работоспособности для интеграции с Kubernetes.
Как обычно, все примеры доступны на GitHub.
«