SmartLifecycle 빈 중지의 가장 이른 단계에서 수행REFUSING_TRAFFIC)와 짝을 이루는 실제 트래픽 드레이닝 동작에 해당| 설정 키 | 기본값 | 역할 |
|---|---|---|
server.shutdown |
graceful |
graceful = 드레이닝 후 종료 / immediate = 즉시 종료 |
spring.lifecycle.timeout-per-shutdown-phase |
30s |
유예 시간 — in-flight 요청을 이 안에서 완료, 초과 시 강제 종료 |
timeout-per-shutdown-phase는 이름대로 phase 단위 타임아웃 — 여러 SmartLifecycle phase 각각에 적용되지만, 웹 앱에서는 사실상 요청 드레이닝 단계의 제한 시간으로 동작SIGTERM으로 전달돼야 graceful이 작동. IDE의 stop 버튼이 SIGTERM을 제대로 안 보내거나 SIGKILL(kill -9)이면 드레이닝 없이 즉시 종료preStop 훅 실행, (3) 컨테이너에 SIGTERM 전송 → (4) terminationGracePeriodSeconds 경과 시 SIGKILLSIGTERM이 Spring graceful shutdown을 트리거하는 진입점 (자세한 종료 시퀀스는 [pod])SIGTERM 직후에도 잠깐 신규 트래픽이 도착할 수 있고, 이미 드레이닝 모드라 거부당함preStop에 짧은 sleep — endpoint 전파가 끝날 시간을 벌어 준 뒤 SIGTERM이 가도록 지연 ([container-lifecycle-hooks])# Deployment의 pod spec
terminationGracePeriodSeconds: 45 # SIGKILL까지의 총 예산 (기본 30)
containers:
- name: app
lifecycle:
preStop:
exec: { command: ["sh", "-c", "sleep 5"] } # endpoint 제거 전파 대기 (K8s 1.29+는 sleep 액션 네이티브 지원)
# application.yml: server.shutdown=graceful, spring.lifecycle.timeout-per-shutdown-phase=30s
terminationGracePeriodSeconds ≥ preStop sleep + timeout-per-shutdown-phase (+여유)
SIGKILL → in-flight 요청 유실. 위 예시는 5 + 30 < 45로 충족