image

Acesse bootcamps ilimitados e +650 cursos

50
%OFF
Article image
Sergio Procopio
Sergio Procopio29/01/2024 11:03
Compartilhe

Liveness and Readiness Probes

    1. Overview

    Neste tutorial, veremos como o Spring Boot 2.3 se integra aos testes do Kubernetes para criar uma experiência nativa da nuvem ainda mais agradável.

    Primeiro, começaremos com um pouco de fundo sobre as sondas do Kubernetes. Em seguida, vamos trocar de marcha e ver como o Spring Boot 2.3 suporta essas sondas.

    2. Kubernetes Probes

    Ao usar o Kubernetes como nossa plataforma de orquestração, o kubelet em cada nó é responsável por manter os pods nesse nó saudáveis.

    Por exemplo, às vezes nossos aplicativos podem precisar de um pouco de tempo antes de serem capazes de aceitar solicitações. O kubelet pode garantir que o aplicativo receba solicitações somente quando estiver pronto. Além disso, se o processo principal de um pod falhar por qualquer motivo, o kubelet reiniciará o contêiner.

    Para cumprir essas responsabilidades, o Kubernetes tem duas sondas: sondas de vivacidade e sondas de prontidão.

    O kubelet usará o teste de prontidão para determinar quando o aplicativo está pronto para aceitar solicitações. Mais especificamente, um pod está pronto quando todos os seus contêineres estiverem prontos.

    Da mesma forma, o kubelet pode verificar se uma cápsula ainda está viva através de sondas vivas. Basicamente, a sonda de vivacidade ajuda o kubelet a saber quando ele deve reiniciar um contêiner.

    Agora que estamos familiarizados com os conceitos, vamos ver como funciona a integração do Spring Boot.

    3. Liveness and Readiness in Actuator

    A partir do Spring Boot 2.3, as classes LivenessStateHealthIndicator e ReadinessStateHealthIndicator exporão o estado de disponibilidade e prontidão do aplicativo. Quando implantamos nosso aplicativo no Kubernetes, o Spring Boot registra automaticamente esses indicadores de integridade.

    Como resultado, podemos usar /actuator/health/liveness e /actuator/health/readiness endpoints como nossas sondas de vida e prontidão, respectivamente.

    Por exemplo, podemos adicioná-los à nossa definição de pod para configurar o teste de vivacidade como uma solicitação HTTP GET:

    livenessProbe:
    httpGet:
      path: /actuator/health/liveness
      port: 8080
      initialDelaySeconds: 3
      periodSeconds: 3
    Copy
    

    Normalmente, deixamos que a Spring Boot decida quando levantar essas sondas para nós. Mas, se quisermos, podemos habilitá-los manualmente em nosso application.properties.

    Se estivermos trabalhando com o Spring Boot 2.3.0 ou 2.3.1, podemos habilitar os testes mencionados através de uma propriedade de configuração:

    management.health.probes.enabled=true
    Copy
    

    No entanto, desde o Spring Boot 2.3.2, essa propriedade foi preterida devido à confusão de configuração.

    Se trabalharmos com o Spring Boot 2.3.2, podemos usar as novas propriedades para habilitar testes de vivacidade e prontidão:

    image

    management.endpoint.health.probes.enabled=true
    management.health.livenessState.enabled=true
    management.health.readinessState.enabled=true
    Copy
    

    3.1. Readiness and Liveness State Transitions

    O Spring Boot usa dois enums para encapsular diferentes estados de prontidão e vivacidade. Para o estado de prontidão, há um enum chamado ReadinessState com os seguintes valores:

    • O estado ACCEPTING_TRAFFIC representa que o aplicativo está pronto para aceitar tráfego
    • O estado REFUSING_TRAFFIC significa que o aplicativo ainda não está disposto a aceitar nenhuma solicitação

    Da mesma forma, o enum LivenessState representa o estado de vivacidade do aplicativo com dois valores:

    • O valor CORRETO significa que o aplicativo está em execução e seu estado interno está correto
    • Por outro lado, o valor BROKEN significa que o aplicativo está sendo executado com algumas falhas fatais

    Veja como o estado de prontidão e vivacidade muda em termos de eventos do ciclo de vida do aplicativo no Spring:

    1. Registrando ouvintes e inicializadores
    2. Preparando o Ambiente
    3. Preparando o ApplicationContext
    4. Carregando definições de bean
    5. Alterando o estado de vivacidade para CORRETO
    6. Chamando o aplicativo e os executores de linha de comando
    7. Alterando o estado de prontidão para ACCEPTING_TRAFFIC

    Quando o aplicativo estiver em funcionamento, nós (e o próprio Spring) podemos alterar esses estados publicando AvailabilityChangeEvents apropriado.

    4. Managing the Application Availability

    Os componentes do aplicativo podem recuperar o estado atual de prontidão e vivacidade injetando a interface ApplicationAvailability:

    @Autowired private ApplicationAvailability applicationAvailability;
    Copy
    

    Então podemos usá-lo da seguinte maneira:

    assertThat(applicationAvailability.getLivenessState())
    .isEqualTo(LivenessState.CORRECT);
    assertThat(applicationAvailability.getReadinessState())
    .isEqualTo(ReadinessState.ACCEPTING_TRAFFIC);
    assertThat(applicationAvailability.getState(ReadinessState.class))
    .isEqualTo(ReadinessState.ACCEPTING_TRAFFIC);
    Copy
    

    4.1. Updating the Availability State

    Também podemos atualizar o estado do aplicativo publicando um evento 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"));
    Copy
    

    Como mostrado acima, antes de publicar qualquer evento, o ponto de extremidade /actuator/health/liveness retorna uma resposta 200 OK com o seguinte JSON:

    {
      "status": "OK"
    }
    Copy
    

    Em seguida, depois de quebrar o estado de disponibilidade, o mesmo ponto de extremidade retorna uma resposta indisponível de serviço 503 com o seguinte JSON:

    {
      "status": "DOWN"
    }
    Copy
    

    Quando mudamos para um estado de prontidão de REFUSING_TRAFFIC, o valor de status será 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"));
    Copy
    

    4.2. Listening to a Change

    Podemos registrar ouvintes de eventos para serem notificados quando um estado de disponibilidade do aplicativo for alterado:

    @Component
    public class LivenessEventListener {
      
      @EventListener
      public void onEvent(AvailabilityChangeEvent<LivenessState> event) {
          switch (event.getState()) {
          case BROKEN:
              // notify others
              break;
          case CORRECT:
              // we're back
          }
      }
    }
    Copy
    

    Aqui estamos ouvindo qualquer mudança no estado de vida do aplicativo.

    5. Auto-Configurations

    Antes de concluir, vamos ver como o Spring Boot configura automaticamente esses testes em implantações do Kubernetes. A classe AvailabilityProbesAutoConfiguration é responsável por registrar condicionalmente os testes de disponibilidade e prontidão.

    De fato, há uma condição especial que registra as sondas quando uma das seguintes situações é verdadeira:

    Quando um aplicativo atende a qualquer uma dessas condições, a configuração automática registra beans de LivenessStateHealthIndicator e ReadinessStateHealthIndicator.

    6. Conclusion

    Neste artigo, vimos como podemos usar o Spring Boot fornece dois testes de integridade para integração com o Kubernetes.

    Compartilhe
    Comentários (0)