ABOUT ME

Today
Yesterday
Total
  • Spring Boot 애플리케이션의 Health Endpoint 상태가 Eureka에 영향을 끼칠까?
    TECH/Spring 2022. 10. 14. 21:34

    결론만 먼저 말하자면 eureka.client.healthcheck.enabled: true인 경우 영향을 끼치고, false(기본값)인 경우 영향을 끼치지 않는다.

    먼저, Spring Boot Actuator의 Health Information이 무엇인지 알아보자.


    Spring Boot Actuator - Health Information

    Health Endpoint란?

    actuator에서 실행 중인 애플리케이션의 상태를 체크하기 위해 제공한다. 일반적으로 프로덕션 환경에서 시스템이 내려갔을 때 이에 대한 알림을 주기 위해 사용된다. 이 정보는 health 엔드포인트에 의해 노출되는데, health endpoint는 management.endpoint.health.show-detailsmanagement.endpoint.health.show-components 설정에 의존하며 이 설정들은 다음 값을 가질 수 있다. 기본 값은 never 이다.

    Name Description
    never Details are never shown.
    when-authorized Details are shown only to authorized users. Authorized roles can be configured by using management.endpoint.health.roles.
    always Details are shown to all users.

    Health 정보는 HealthContributorRegistry (기본적으로 모든 HealthContributor 인스턴스는 ApplicationContext 내에 정의되어 있다.)의 내용에서 수집된다. Spring Boot는 자동 설정된 여러 HealthContributors를 포함하고 있고, 직접 HealthContributors 를 만들 수도 있다.

    HealthContributorHealthIndicator 혹은 CompositeHealthContributor 이다. HealthIndicator 는 status를 포함한 실제 health 정보를 제공한다. CompositeHealthContributor는 다른 HealthContributors들을 취합하여 제공한다. 합쳐서, contributors는 시스템 전반의 health에 대한 트리 구조를 형성하게 된다.

    기본적으로 최종 시스템 health는 정렬된 상태 리스트를 기반으로 각 HealthIndicator의 상태를 정렬하는 StatusAggregator 를 통해서 얻게 된다. 정렬된 리스트의 첫번째 상태는 시스템 전반의 health 상태이다. 만약 아무런 HealthIndicatorStatusAggregator에 알려진 상태를 응답하지 않는다면, UNKNOWN 상태가 사용된다.

    Reactive Health Indicators

    Spring WebFlux와 같은 리액티브 애플리케이션의 경우 ReactiveHealthContributor가 애플리케이션의 health 정보를 얻기 위한 non-blocking 방식을 제공한다. 기존 HealthContributor와 유사하게, health 정보는 ReactiveHealthContributorRegistry 를 통해 수집된다. (기본적으로 모든 HealthContributorReactiveHealthContributor 인스턴스는 ApplicationContext 내에 정의되어 있다.) reactive API에 대해 체크를 하지 않는 일반적인 HealthContributors 는 elastic scheduler로 동작한다.

    다음으로 유레카에서 클라이언트의 상태를 어떻게 확인하는지 알아보자.


    Spring Cloud Netflix

    Registering with Eureka

    클라이언트가 유레카에 등록될 때, host, port, health indicator, homepage URL 등과 같은 자신에 대한 메타데이터를 제공한다. 유레카는 서비스에 속하는 각 인스턴스로부터 heartbeat 메시지를 수신한다. 설정된 timetable 동안 heartbeat에 실패하면 인스턴스는 자동으로 레지스트리에서 제거된다.

    요약 : eureka에 인스턴스를 등록할 때는 actuator의 health 가 사용되지 않는다. heartbeat를 통해서 동작한다.

    Eureka's Health Checks

    기본적으로 유레카는 클라이언트가 UP 상태인지를 확인하기 위해 클라이언트 하트비트를 사용한다. 특별히 설정되어 있지 않는 한, 디스커버리 클라이언트는 액츄에이터별 애플리케이션의 현재 헬스 체크 상태를 전파하지 않는다. 따라서, 성공적인 등록 후 유레카는 항상 애플리케이션의 상태를 UP으로 나타낸다. 이 동작은 유레카의 헬스체크 설정(eureka.client.healthcheck.enabled: true)을 활성화 함으로서 변경할 수 있는데, 이렇게 할 경우 애플리케이션의 상태가 유레카로 전파된다. 결과적으로 모든 다른 애플리케이션은 UP 상태가 아닌 애플리케이션에 트래픽을 보내지 않게 된다.

    요약 : 유레카에 등록된 클라이언트의 상태를 확인할 때에도 eureka에 인스턴스를 등록할 때와 마찬가지로 기본적으로 하트비트를 사용한다. 유레카에 등록된 클라이언트의 상태체크를 위해 actuator의 health 상태를 사용하려면 eureka.client.healthcheck.enabled: true로 설정해야 한다.


    실제로 eureka.client.healthcheck.enabled 값을 바꿔가면서 동작을 확인해보자.

    테스트에 사용되는 코드를 간단히 설명하면 다음과 같다.

    1. Eureka 서버와 클라이언트 애플리케이션
    2. 클라이언트 애플리케이션에서는 r2dbc 관련 의존성을 추가한다. 그리고 (존재하지 않는) 임의의 데이터베이스 URL을 설정하여 의도적으로 데이터베이스 관련 설정이 비정상으로 나타나도록 한다.

    테스트 1. eureka.client.healthcheck.enabled=false(기본값)

    1. /actuator/health 확인시스템 전반의 상태는 DOWN이다.
    2. {
         "status":"DOWN",
         "components":{
            "discoveryComposite":{
               "status":"UP",
               "components":{
                  "discoveryClient":{
                     "status":"UP",
                     "details":{
                        "services":[
                           "eureka-demo",
                           "eureka-client"
                        ]
                     }
                  },
                  "eureka":{
                     "description":"Remote status from Eureka server",
                     "status":"UP",
                     "details":{
                        "applications":{
                           "EUREKA-DEMO":1,
                           "EUREKA-CLIENT":1
                        }
                     }
                  }
               }
            },
            "diskSpace":{
               "status":"UP",
               "details":{
                  "total":499963174912,
                  "free":215447891968,
                  "threshold":10485760,
                  "exists":true
               }
            },
            "ping":{
               "status":"UP"
            },
            "r2dbc":{
               "status":"DOWN",
               "details":{
                  "database":"Jasync-MySQL",
                  "validationQuery":"validate(REMOTE)",
                  "error":"io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: localhost/127.0.0.1:3306"
               }
            },
            "reactiveDiscoveryClients":{
               "status":"UP",
               "components":{
                  "Simple Reactive Discovery Client":{
                     "status":"UP",
                     "details":{
                        "services":[
      
                        ]
                     }
                  },
                  "Spring Cloud Eureka Reactive Discovery Client":{
                     "status":"UP",
                     "details":{
                        "services":[
                           "eureka-demo",
                           "eureka-client"
                        ]
                     }
                  }
               }
            },
            "refreshScope":{
               "status":"UP"
            }
         }
      }
    3. eureka에 등록된 서비스의 상태 확인

    Eureka dashboard에 접속해 확인

    Status가 UP임을 확인할 수 있다.

    테스트 2. eureka.client.healthcheck.enabled=true

    1. /actuator/health 확인

    테스트1과 동일하게 시스템 전반의 상태는 DOWN이다.

    {
      "description": "Remote status from Eureka server",
      "status": "DOWN",
      "components": {
        "discoveryComposite": {
          "description": "Remote status from Eureka server",
          "status": "DOWN",
          "components": {
            "discoveryClient": {
              "status": "UP",
              "details": {
                "services": [
                  "eureka-demo"
                ]
              }
            },
            "eureka": {
              "description": "Remote status from Eureka server",
              "status": "DOWN",
              "details": {
                "applications": {
                  "EUREKA-DEMO": 1
                }
              }
            }
          }
        },
        "diskSpace": {
          "status": "UP",
          "details": {
            "total": 499963174912,
            "free": 215452540928,
            "threshold": 10485760,
            "exists": true
          }
        },
        "ping": {
          "status": "UP"
        },
        "r2dbc": {
          "status": "DOWN",
          "details": {
            "database": "Jasync-MySQL",
            "validationQuery": "validate(REMOTE)",
            "error": "io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: localhost/127.0.0.1:3306"
          }
        },
        "reactiveDiscoveryClients": {
          "status": "UP",
          "components": {
            "Simple Reactive Discovery Client": {
              "status": "UP",
              "details": {
                "services": []
              }
            },
            "Spring Cloud Eureka Reactive Discovery Client": {
              "status": "UP",
              "details": {
                "services": [
                  "eureka-demo"
                ]
              }
            }
          }
        },
        "refreshScope": {
          "status": "UP"
        }
      }
    }
    1. eureka에 등록된 서비스의 상태 확인

    Eureka dashboard에 접속해 확인

    테스트1과 달리 Status가 DOWN임을 확인할 수 있다.


    요약

    Spring Boot Actuator에서 제공하는 Health 정보는 Eureka Client에서 eureka.client.healthcheck.enabled: true로 설정한 경우에만 eureka 서버에 등록된 서비스의 헬스체크에 사용된다.

     

    참고

    https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.endpoints.health

    https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.endpoints.health.reactive-health-indicators

    https://docs.spring.io/spring-cloud-netflix/docs/current/reference/html/#registering-with-eureka

    https://docs.spring.io/spring-cloud-netflix/docs/current/reference/html/#eurekas-health-checks

Designed by Tistory.