HTTP 200 OK

Memento mori & Carpe diem

CS

API 헬스체크

sjoongh 2023. 8. 17. 14:56

헬스체크란?

  • 서비스의 고가용성(HA, High Availability), 고성능을 위한 부하 분산 등의 이유로 우리는 서버의 이중화(혹은 그 이상)를 하고, 앞에서 어떤 서버로 요청을 보낼지 라우팅 역할을 하는 로드 밸런서를 둔다.
  • 로드 밸런서는 부하를 적절히 분산하여 구축된 여러 서버중 한대에게 클라이언트의 요청을 보낸다.
  • 하지만 요청을 한 서버가 서비스 불가상태라거나 소스코드를 로딩하고 있을 경우에는 서버로 요청을 보내면 안된다. → (장애 유발과 더불어 부하를 더 증가시키기 때문이다)
  • 때문에 로드 밸런서에서는 각 서버의 헬스 체크 API를 호출해서 해당 서버가 현재 서비스 가능한 상태인지 아닌지 주기적으로 체크한다.
  • 즉 헬스 체크는 정상적으로 서비스가 가능한 서버에만 트래픽을 보내서 서비스의 고가용성을 확보하는데 도움이 된다.

 

간단히 요약하자면 health check api는 현재 서버의 상태가 정상인지 여부를 확인하는 것이다. 서버 실행 전반(전,중,후)에 걸쳐서 손쉽게 서버의 상태를 확인할 때 사용하기 좋다.

 

build.gradle 설정

implementation 'org.springframework.boot:spring-boot-starter-actuator'
  • 해당 의존성을 추가한 뒤 어플리케이션을 실행하면 /autuator/health API가 기본으로 제공된다.

 

health API endpoint를 수정하고 싶다면
  • 만약 API 경로를 /health와 같이 수정하고 싶다면 어떻게 해야할까, 이럴 땐 application의 설정 파일에 관련 옵션을 추가하면 된다.
management.endpoints.web.base-path=/
  • base-path의 기본값은 actuator이다. 설정을/ 로 수정하면 기존의 API를 /actuator/health → /health 로 수정할 수 있다.
DB 상태도 받고 싶다면
management.endpoint.health.show-details=always
disk 정보만 빼고 싶다면
management.health.diskspace.enabled=false
기존 응답에 custom 한 응답을 추가하고 싶다면
@Component
public class OtherServerHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        int httpStatus = 200; // 여기서 서버로 ping을 날리든, health api를 호출하든 응답을 받는다.
        if (httpStatus == HttpStatus.OK.value()) {
            return Health.up().build();
        }

        return Health.down().build();
    }
}
  • custom한 health 객체를 추가하고 싶다면 HealthIndicator 인터페이스를 구현하면 된다.

 

결과

앞서 설정한 값들에 따라서 아래의 사진과 같은 결과값을 받을 수 있다.

헬스체크 결과

 

엔드포인트 상세

  • /health 엔드포인트에서 서버의 상태를 받아올 수 있다. 해당 상태는 다음과 같다.
    • UP : 외부 시스템이 작동 중이고 접근 가능하다.
    • DOWN : 외부 시스템이 작동하지 않거나 접근할 수 없다.
    • OUT_OF_SERVICE : 외부 시스템의 상태가 분명하지 않다.
    • UNKNOWN : 외부 시스템에 접근할 수 있지만, 현재는 사용할 수 없다.

 

API 헬스 체크 사용

활용하면 좋은 사례
  1. API 상태 확인 자동화
  2. 캐시 비활성화
  3. 응답시간문제
  4. JSON

 

헬스체크에서 조심해야할 점

  • 각 서버에 서비스를 제공하는 서비스 DB와 데이터를 분석하는 로그 DB가 있다고 할 때 그리고 로그 DB에 적재하는 작업은 비동기로 별도의 스레드에서 처리하도록 작업되어 있을때 로그 데이터 저장이 불가능하더라도 실시간 서비스에는 문제가 업도록 하기 위해 이런작업을 한다.
  • 이때 만약 로그 DB에 작업을 해야해서 순단이 발생하거나 접속에 문제가 발생한다면?

  • Spring Boot Actuator의 헬스 체크는 여러 HealthIndicator가 수집한 상태를 토대로 서비스의 상태를 판단한다. 다음은 그 순서이다.
  1. RoutingDataSourceHealthContributor 에 의해 여러 DataSource의 헬스를 체크한다.
    1. DataSourceHealthIndicator에 의해 서비스 DB의 상태를 체크했을 때는 UP이 반환된다.
    2. DataSourceHealthIndicator에 의해 로그 DB의 상태를 체크했을 때는 Down이 반환된다.
  2. 수집한 상태들은 SimpleStatusAggregator에 의해 서비스 상태를 판단하게 되는데 아무런 순서를 설정하지 않았으면 DOWN인게 하나라도 있을경우 DOWN이 반환된다.
  3. 서비스의 상태가 DOWN(503)으로 판단됐기 때문에 로드 밸런서에서는 서버로 트래픽을 보내지 않게 된다.
  4. 서비스 DB에 문제가 없음에도 불구하고 클라이언트의 요청은 처리되지 않고 장애가 발생한다.

 

로그 DB의 장애가 전파되지 않도록 격리했음에도 장애가 발생할 수 있다. 이를 해결하기 위한 방법은 다음과 같다.
  1. Spring Boot Actuator의 헬스 체크가 아닌 직접 헬스 체크 API를 구현할 수도 있다.
  2. HealthIndicator 중에 헬스 체크에 영향을 끼치지 않길 희망하는 것들은 비활성화 시키는 방법도 있다. (RDB를 예로 들자면 management.health.db.enabled:false(기본값 true)로 설정한다거나)
  3. 문제가 되는 HealthIndicator 빈을 직접 생성해서 Auto Configuration의 동작을 오버라이딩 하는 방법 등등이 있다.

 

출처

https://docs.spring.io/spring-boot/docs/3.0.5/reference/html/actuator.html#actuator

'CS' 카테고리의 다른 글

Connection Pool 테스트와 고찰(1)  (0) 2023.11.07
Cold Stream vs Hot Stream 이란?  (1) 2023.10.31
Connection pool  (0) 2022.12.06
WebFlux  (0) 2022.11.06
pinPoint  (0) 2022.11.06