Рубрики
Без рубрики

Показатели здоровья в весенней загрузке

Узнайте все о показателях здоровья в весенней загрузке.

Автор оригинала: Mona Mohamadinia.

1. Обзор

Spring Boot предоставляет несколько различных способов проверки состояния и состояния запущенного приложения и его компонентов. Среди этих подходов HealthContributor и ЗдоровьеИндикатор API являются двумя из примечательных.

В этом учебнике мы собираемся ознакомиться с этими API, узнать, как они работают, и посмотреть, как мы можем внести пользовательскую информацию к ним.

2. Зависимости

Вкладчики информации о здоровье являются частью Весенняя загрузка актуатор модуль, поэтому нам нужна соответствующая Maven зависимость :


    org.springframework.boot
    spring-boot-starter-actuator

3. Встроенные медицинскиеиндикаторы

Из коробки, Весенняя загрузка регистрирует многие ЗдоровьеИндикатор s сообщать о состоянии здоровья конкретного аспекта применения .

Некоторые из этих показателей почти всегда регистрируются, например DiskSpaceHealthИндикатор или PingHealthИндикатор . Первый сообщает о текущем состоянии диска, а второй служит конечной точкой для приложения.

С другой стороны, Spring Boot регистрирует некоторые индикаторы условно . То есть, если некоторые зависимости находятся на classpath или некоторые другие условия будут выполнены, Spring Boot может зарегистрировать несколько других ЗдоровьеИндикатор s, слишком. Например, если мы используем реляционные базы данных, то Spring Boot регистрирует ДанныеИсточникЗдоровьеИндикатор . Аналогичным образом, он будет регистрировать КассандраЗдоровьеИндикатор если нам случится использовать Кассандра в качестве нашего хранения данных.

Для проверки состояния здоровья приложения Spring Boot мы можем вызвать /Актуатор/здоровье конечная точка . Эта конечная точка будет сообщать агрегированный результат всех зарегистрированных ЗдоровьеИндикатор секунда.

Кроме того, чтобы увидеть отчет о состоянии здоровья по одному конкретному индикатору, мы можем назвать /актуатор/здоровье/имя) конечная точка . Например, вызов /актуатор/здоровье/diskSpace конечная точка вернет отчет о состоянии из DiskSpaceHealthИндикатор :

{
  "status": "UP",
  "details": {
    "total": 499963170816,
    "free": 134414831616,
    "threshold": 10485760,
    "exists": true
  }
}

4. Пользовательские HealthIndicators

В дополнение к встроенным, мы можем зарегистрировать пользовательские ЗдоровьеИндикатор s сообщать о работе компонента или подсистемы. Для этого, все, что нам нужно сделать, это зарегистрировать осуществление ЗдоровьеИндикатор интерфейс как весенний бобовый .

Например, следующая реализация сообщает о сбое случайным образом:

@Component
public class RandomHealthIndicator implements HealthIndicator {

    @Override
    public Health health() {
        double chance = ThreadLocalRandom.current().nextDouble();
        Health.Builder status = Health.up();
        if (chance > 0.9) {
            status = Health.down();
        }
        return status.build();
    }
}

Согласно отчету о состоянии здоровья по этому показателю, приложение должно быть только 90% времени. Здесь мы используем Здравоохранение сообщить информацию о состоянии здоровья.

В реактивных приложениях, однако, мы должны зарегистрировать фасоль типа Реактивный ЗдоровьеИндикатор . Реактивная здоровья () метод возвращает Моно вместо простого Здравоохранение . Помимо этого, другие детали одинаковы для обоих типов веб-приложений.

4.1. Имя индикатора

Чтобы увидеть отчет по данному конкретному индикатору, мы можем назвать /актуатор/здоровье/случайный конечная точка. Например, вот как может выглядеть ответ API:

{"status": "UP"}

случайные в /актуатор/здоровье/случайный URL-адрес является идентификатором для этого индикатора. Идентификатор для конкретного ЗдоровьеИндикатор реализация равна названию фасоли без ЗдоровьеИндикатор суффикс. Так как имя фасоли randomHealthIdenticator , случайные префикс будет идентификатором.

С помощью этого алгоритма, если мы изменим название фасоли, скажем, ранд :

@Component("rand")
public class RandomHealthIndicator implements HealthIndicator {
    // omitted
}

Затем идентификатор индикатора будет ранд вместо случайные .

4.2. Отключение индикатора

Чтобы отключить определенный индикатор, мы можем установить management.health. .enabled” свойство конфигурации для ложных . Например, если мы добавим следующее к нашему application.properts :

management.health.random.enabled=false

Затем Spring Boot отключит Случайный ЗдоровьеИндикатор . Чтобы активировать это свойство конфигурации, мы также должны добавить @ConditionalOnEnabledHealthIndicator аннотация по индикатору:

@Component
@ConditionalOnEnabledHealthIndicator("random")
public class RandomHealthIndicator implements HealthIndicator { 
    // omitted
}

Теперь, если мы позвоним /актуатор/здоровье/случайный , Весенняя загрузка вернет 404 Не найдено ОТВЕТ HTTP:

@SpringBootTest
@AutoConfigureMockMvc
@TestPropertySource(properties = "management.health.random.enabled=false")
class DisabledRandomHealthIndicatorIntegrationTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void givenADisabledIndicator_whenSendingRequest_thenReturns404() throws Exception {
        mockMvc.perform(get("/actuator/health/random"))
          .andExpect(status().isNotFound());
    }
}

Обратите внимание, что отключение встроенных или пользовательских индикаторов аналогично друг другу. Таким образом, мы можем применить ту же конфигурацию и к встроенным индикаторам.

4.3. Дополнительные сведения

В дополнение к отчетности о состоянии, мы можем прикрепить дополнительные ключевые значения детали с помощью сДайв (ключ, значение) :

public Health health() {
    double chance = ThreadLocalRandom.current().nextDouble();
    Health.Builder status = Health.up();
    if (chance > 0.9) {
        status = Health.down();
    }

    return status
      .withDetail("chance", chance)
      .withDetail("strategy", "thread-local")
      .build();
}

Здесь мы добавляем две части информации в отчет о состоянии. Кроме того, мы можем достичь того же, передавая Карта<Стринг, объект> к сдевами (карта) метод:

Map details = new HashMap<>();
details.put("chance", chance);
details.put("strategy", "thread-local");
        
return status.withDetails(details).build();

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

{
  "status": "DOWN",
  "details": {
    "chance": 0.9883560157173152,
    "strategy": "thread-local"
  }
}

Мы также можем проверить такое поведение с помощью автоматизированного теста:

mockMvc.perform(get("/actuator/health/random"))
  .andExpect(jsonPath("$.status").exists())
  .andExpect(jsonPath("$.details.strategy").value("thread-local"))
  .andExpect(jsonPath("$.details.chance").exists());

Иногда исключение происходит при общении с системными компонентами, такими как база данных или диск. Мы можем сообщать о таких исключениях с помощью сЭксцепция (например) метод:

if (chance > 0.9) {
    status.withException(new RuntimeException("Bad luck"));
}

Мы также можем передать исключение из вниз (например) метод, который мы видели ранее:

if (chance > 0.9) {
    status = Health.down(new RuntimeException("Bad Luck"));
}

Теперь отчет о состоянии здоровья будет содержать след стека:

{
  "status": "DOWN",
  "details": {
    "error": "java.lang.RuntimeException: Bad Luck",
    "chance": 0.9603739107139401,
    "strategy": "thread-local"
  }
}

4.4. Подробная информация об экспозиции

тем management.endpoint.health.show-details Свойство конфигурации контролирует уровень деталей, которые может выставить каждая конечная точка состояния.

Например, если мы будем устанавливать это свойство всегда, то Весенняя загрузка всегда будет возвращать подробная информация в отчете о состоянии здоровья, как и в приведенной выше примере.

С другой стороны, если мы будем устанавливать это свойство никогда , то весенняя загрузка всегда опустить подробная информация от выходных . Существует также when_authorized значение, которое предоставляет дополнительную подробная информация только для авторизованных пользователей. Пользователь уполномочен, если и только если:

  • Она проверена
  • И она обладает ролями, указанными в management.endpoint.health.roles свойство конфигурации

4.5. Состояние здоровья

По умолчанию Spring Boot определяет четыре различных значения как Статус :

  • UP – Компонент или подсистема работает в том, что
  • ВНИЗ – Компонент не работает
  • OUT_OF_SERVICE – Компонент временно вышел из эксплуатации
  • НЕИЗВЕСТНЫЕ – Состояние компонента неизвестно

Эти государства объявлены публичный статический финальный экземпляров вместо Java enums. Таким образом, можно определить наши собственные пользовательские состояния здоровья. Для этого мы можем использовать статус (имя) метод:

Health.Builder warning = Health.status("WARNING");

Состояние здоровья влияет на код статуса HTTP конечной точки . По умолчанию Spring Boot отображает ВНИЗ , и OUT_OF_SERVICE состояния для броска кода статуса 503. С другой стороны, ВВЕРХ и любые другие неразмескавшиеся статусы будут переведены на код статуса 200 OK.

Чтобы настроить это отображение, мы можем установить management.endpoint.health.status.http-mapping. на нужный кодовое число http:

management.endpoint.health.status.http-mapping.down=500
management.endpoint.health.status.http-mapping.out_of_service=503
management.endpoint.health.status.http-mapping.warning=500

Теперь Весенняя загрузка будет карта ВНИЗ статус до 500, OUT_OF_SERVICE до 503, и ВНИМАНИЕ до 500 кодов статуса HTTP:

mockMvc.perform(get("/actuator/health/warning"))
  .andExpect(jsonPath("$.status").value("WARNING"))
  .andExpect(status().isInternalServerError());

Аналогичным образом, мы можем зарегистрировать фасоль типа HttpCodeStatusMapper настроить отображение кода статуса HTTP :

@Component
public class CustomStatusCodeMapper implements HttpCodeStatusMapper {

    @Override
    public int getStatusCode(Status status) {
        if (status == Status.DOWN) {
            return 500;
        }
        
        if (status == Status.OUT_OF_SERVICE) {
            return 503;
        }
        
        if (status == Status.UNKNOWN) {
            return 500;
        }

        return 200;
    }
}

getStatusCode (статус) метод принимает состояние здоровья в качестве ввода и возвращает код статуса HTTP в качестве вывода. Кроме того, можно сопоставить пользовательские Статус Экземпляров:

if (status.getCode().equals("WARNING")) {
    return 500;
}

По умолчанию Spring Boot регистрирует простую реализацию этого интерфейса с помощью карт по умолчанию. SimpleHttpCodeStatusMapper также способен читать отображения из файлов конфигурации, как мы видели ранее.

5. Информация о здоровье против метрики

Нетривиальные приложения обычно содержат несколько различных компонентов. Например, рассмотрите приложения Spring Boot, использующие Cassandra в качестве базы данных, Apache Kafka в качестве платформы pub-sub и Hazelcast в качестве сетки данных в памяти.

Мы должны использовать ЗдоровьеИндикатор s, чтобы увидеть, может ли приложение общаться с этими компонентами или . Если связь выходит из строя или сам компонент не работает или замедляется, то у нас есть нездоровый компонент, который мы должны знать. Другими словами, эти показатели следует использовать для сообщения о состоянии здоровья различных компонентов или подсистем.

Напротив, мы должны избегать использования ЗдоровьеИндикатор s для измерения значений, подсчета событий или измерения продолжительности. Вот почему у нас есть метрики. Проще говоря, метрики являются лучшим инструментом для сообщения об использовании процессора, среднем нагрузке, размере кучи, распределении ответов HTTP и так далее.

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

В этом учебнике мы увидели, как внести больше информации о здоровье в конечные точки здоровья привода. Кроме того, мы имели углубленный охват различных компонентов API в области здравоохранения, таких как Здравоохранение , Статус , и состояние отображения статуса HTTP.

Чтобы завершить работу, мы провели быструю дискуссию о разнице между информацией о здоровье и метриками, а также узнали, когда использовать каждый из них.

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