본문으로 건너뛰기
Advertisement

실전 고수 팁 — Graceful Shutdown 아키텍처 및 무중단 배포를 위한 설정

실무에서 배포를 진행할 때 현재 처리 중인 요청을 강제로 끊어버리면 심각한 데이터 손실이나 결제가 끊기는 롤백 이슈가 발생합니다. 이를 위해 안전하게 종료하는 Graceful Shutdown 구성이 필수적입니다.

1. Graceful Shutdown 설정

스프링 부트 2.3부터 내장된 Graceful Shutdown 기능을 켜주기만 하면 됩니다. 이 속성을 켜면 애플리케이션 종료 신호(SIGTERM) 수신 시 새로운 요청은 거절(HTTP 503)하되, 이미 들어온 요청은 일정 시간 동안 처리 완료할 수 있도록 기다립니다.

server:
shutdown: graceful # 기본값은 immediate 입니다.

spring:
lifecycle:
timeout-per-shutdown-phase: 30s # 최대 30초 대기

2. 쿠버네티스(k8s) / 로드밸런서 연동

단순히 스프링 부트 설정만 켠다고 끝나는 것이 아닙니다. 스프링이 새로운 요청을 끊기 시작했을 때, L4 스위치나 Kubernetes의 Service(Ingress)가 이를 즉각 인지하고 트래픽을 다른 정상 노드로 돌려야 합니다.

스프링의 Actuator를 활용해 "배포 중지 상태"를 알립니다.

management:
endpoint:
health:
probes:
enabled: true
health:
livenessstate:
enabled: true
readinessstate:
enabled: true
  • livenessProbe: 서버가 죽었는지 판단 (실패 시 앱 재시작)
  • readinessProbe: 서버가 올바르게 요청을 받을 준비가 되었는지 판단 (실패 시 로드밸런서 타겟 그룹에서 일시 분리)

서버 종료가 시작되면 readiness 상태가 즉시 OUT_OF_SERVICE로 변경되어, 로드밸런서가 더 이상 이 노드에 트래픽을 분배하지 않습니다.

배포 스크립트 작성 시 "SIGKILL(kill -9)" 대신 반드시 "SIGTERM(kill -15)"를 보내야 Graceful Shutdown이 유효하게 동작합니다. 도커(Docker)의 docker stop 명령이나 쿠버네티스의 파드 제거 명령은 기본적으로 SIGTERM을 발생시킵니다.

Advertisement