Перейти к основному содержимому

Проверка работоспособности и готовности в Spring Boot

· 5 мин. чтения

1. Обзор

В этом руководстве мы увидим, как Spring Boot 2.3 интегрируется с зондами Kubernetes , чтобы создать еще более приятный облачный опыт.

Во-первых, мы начнем с небольшого предыстории зондов Kubernetes. Затем мы переключим передачу и посмотрим, как Spring Boot 2.3 поддерживает эти зонды.

2. Зонды Kubernetes

При использовании Kubernetes в качестве нашей платформы для оркестровки kubelet в каждом узле отвечает за поддержание работоспособности модулей в этом узле.

Например, иногда нашим приложениям может потребоваться некоторое время, прежде чем они смогут принимать запросы. Кублет может сделать так, чтобы приложение получало запросы только тогда, когда оно готово. Кроме того, если по какой-либо причине происходит сбой основного процесса пода, kubelet перезапустит контейнер.

Для выполнения этих обязанностей в Kubernetes есть два зонда: зонды живучести и зонды готовности.

Кублет будет использовать датчик готовности, чтобы определить, когда приложение готово принимать запросы. Точнее, модуль готов, когда готовы все его контейнеры.

Точно так же kubelet может проверить, жив ли под, с помощью liveness probes . По сути, liveness probe помогает kubelet узнать, когда следует перезапустить контейнер.

Теперь, когда мы знакомы с концепциями, давайте посмотрим, как работает интеграция Spring Boot.

3. Жизнеспособность и готовность актуатора

Начиная с 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:

  1. Регистрация слушателей и инициализаторов
  2. Подготовка среды
  3. Подготовка контекста приложения
  4. Загрузка определений компонентов
  5. Изменение состояния живучести на ПРАВИЛЬНОЕ
  6. Вызов приложения и исполнителей командной строки
  7. Изменение состояния готовности на ACCEPTING_TRAFFIC

Как только приложение запущено и запущено, мы (и сам Spring) можем изменить эти состояния, опубликовав соответствующие AvailabilityChangeEvents .

4. Управление доступностью приложений

Компоненты приложения могут получить текущее состояние готовности и жизнеспособности, внедрив интерфейс ApplicationAvailability :

@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 возвращает ответ 200 OK со следующим JSON:

{
"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 .

Когда приложение соответствует любому из этих условий, автоконфигурация регистрирует компоненты LivenessStateHealthIndicator и ReadinessStateHealthIndicator.

6. Заключение

В этой статье мы увидели, как мы можем использовать Spring Boot, который предоставляет две проверки работоспособности для интеграции Kubernetes.

Как обычно, все примеры доступны на GitHub .