본문 바로가기

Programming/Spring Boot

Spring Boot Actuator readiness·liveness 설정: 배포 트래픽을 안전하게 제어하는 방법

추천캐릭터 2026. 8. 6. 17:58
728x90

Spring Boot Actuator readiness·liveness 설정: 배포 트래픽을 안전하게 제어하는 방법

메타 설명: Spring Boot Actuator의 liveness와 readiness 차이를 이해하고, Kubernetes probe와 운영 설정을 구성해 장애 전파와 배포 중 요청 실패를 줄이는 방법을 정리합니다.

새 버전을 배포했는데 컨테이너가 실행되자마자 요청이 들어와 503이 발생하거나, 데이터베이스 장애 순간 모든 인스턴스가 연달아 재시작되는 일이 있습니다. 두 상황은 모두 “애플리케이션이 건강한가?”라는 질문을 하나의 체크로 처리할 때 생기기 쉽습니다.

Spring Boot Actuator는 생존 여부를 판단하는 liveness와 트래픽 수신 가능 여부를 판단하는 readiness를 분리합니다. 두 신호를 제대로 나누면 재시작해야 할 인스턴스와 잠시 트래픽에서 제외할 인스턴스를 다르게 처리할 수 있습니다.

liveness와 readiness는 질문이 다르다

구분 liveness readiness
질문 프로세스가 스스로 회복 불가능한가? 지금 요청을 받아도 되는가?
실패 시 동작 컨테이너 재시작 서비스 엔드포인트에서 제외
대표 원인 내부 상태 손상, 복구 불가능한 교착 초기화 중, 일시적 과부하, 필수 준비 미완료
외부 DB 포함 원칙적으로 제외 영향과 장애 전파를 검토한 뒤 선택

DB 지연을 liveness 실패로 처리하면 정상 프로세스까지 재시작하며 장애가 커질 수 있습니다. 반대로 준비가 끝나지 않은 인스턴스의 readiness가 UP이면 요청이 너무 일찍 들어옵니다.

Actuator 의존성과 기본 설정

Maven 프로젝트에는 Actuator를 추가합니다. Spring Boot BOM을 사용한다면 별도의 버전을 적지 않습니다.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

운영 설정은 다음처럼 시작할 수 있습니다.

management:
  endpoints:
    web:
      exposure:
        include: health,info
  endpoint:
    health:
      probes:
        enabled: true
        add-additional-paths: true
      show-details: never

Actuator는 /actuator/health/liveness/actuator/health/readiness를 제공합니다. add-additional-paths를 켜면 주 서버 포트에도 /livez, /readyz가 생겨 실제 웹 서버를 검사할 수 있습니다.

노출 범위를 *로 열지 말고, 나머지 관리 엔드포인트는 별도 포트·방화벽·Spring Security로 제한합니다.

Kubernetes probe 연결

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-api
spec:
  template:
    spec:
      containers:
        - name: order-api
          image: example/order-api:1.0.0
          ports:
            - containerPort: 8080
          startupProbe:
            httpGet:
              path: /livez
              port: 8080
            periodSeconds: 5
            failureThreshold: 30
          livenessProbe:
            httpGet:
              path: /livez
              port: 8080
            periodSeconds: 10
            failureThreshold: 3
          readinessProbe:
            httpGet:
              path: /readyz
              port: 8080
            periodSeconds: 5
            failureThreshold: 2

startupProbe가 성공하기 전에는 liveness 판정이 미뤄집니다. 위 숫자는 예시이므로 콜드 스타트와 GC 정지 시간을 측정해 임계값을 조정합니다.

readiness에 DB를 넣을 때의 트레이드오프

Spring Boot는 기본 readiness 그룹에 모든 외부 의존성을 자동으로 넣지 않습니다. DB 상태를 포함하려면 명시적으로 구성할 수 있습니다.

management:
  endpoint:
    health:
      group:
        readiness:
          include: readinessState,db

DB가 필수인 서비스에는 합리적일 수 있습니다. 그러나 공유 DB 장애 때 모든 인스턴스가 동시에 제외될 수 있습니다. 캐시나 지연 처리 경로가 있다면 DB를 빼고 회로 차단기와 기능별 오류로 대응합니다.

로컬에서 검증하는 방법

curl -i http://localhost:8080/actuator/health/liveness
curl -i http://localhost:8080/actuator/health/readiness
curl -i http://localhost:8080/livez
curl -i http://localhost:8080/readyz

HTTP 200과 {"status":"UP"}을 확인한 뒤 준비 지연, DB 차단, 종료 신호를 재현해 로드밸런서 제외 시점을 기록합니다.

흔한 실수

  • liveness에 DB·Redis·외부 API를 모두 포함해 공유 장애를 재시작 폭풍으로 바꾼다.
  • readiness와 liveness가 같은 의미라고 보고 동일한 실패 조건을 사용한다.
  • 별도 관리 포트만 검사해 실제 HTTP 포트 장애를 놓친다.
  • probe 간격과 임계값을 측정 없이 짧게 잡아 순간적인 지연에도 재시작한다.
  • Actuator 전체 엔드포인트와 상세 정보를 인터넷에 공개한다.

핵심 요약

  • liveness는 재시작 판단, readiness는 트래픽 수신 판단이다.
  • 외부 시스템 장애를 liveness에 넣지 않는 것이 기본 원칙이다.
  • 별도 관리 포트를 쓴다면 /livez, /readyz를 주 서버 포트에도 노출해 거짓 양성을 줄인다.
  • readiness의 DB 포함 여부는 대체 경로와 전체 인스턴스 동시 제외 위험을 보고 결정한다.
  • probe 숫자는 실제 시작 시간과 장애 복구 시간을 측정한 뒤 조정한다.

함께 읽기

최종 확인: 2026-08-03

공식 출처:

728x90