WAS를 배포할 때마다 약 1~2초간 502 에러가 발생했다. 로드밸런서 뒤에 WAS가 두 대 있고, 순차적으로 배포하니까 무중단 배포인 줄 알았는데 실제로는 502가 찍히고 있었다.
구조
[클라이언트]
│
▼
[로드밸런서] ──────────► 헬스체크
│
├── [WAS-01]
└── [WAS-02]
WAS-02를 배포 중 → WAS-01만 살아있어야 함 → 근데 502가 발생
원인 분석
문제 1: WAS가 종료되는데 로드밸런서가 모른다
로드밸런서 헬스체크 설정이 느슨했다. 헬스체크 주기가 30초, WAS가 종료 신호를 받고 실제로 죽는 데 1초도 안 걸렸다.
배포 시작
│
├── WAS-02 종료 신호 수신
├── WAS-02 즉시 종료 (처리 중인 요청 버림)
│
└── 로드밸런서: WAS-02가 죽은 줄 모름 (헬스체크까지 30초 남음)
└── WAS-02로 요청 계속 전달 → 502
문제 2: 처리 중인 요청을 그냥 버렸다
SIGTERM 신호를 받으면 Spring Boot 앱이 그냥 종료됐다.
진행 중이던 HTTP 요청들이 응답을 받지 못하고 연결이 끊겼다.
해결 1: Graceful Shutdown 활성화
Spring Boot 2.3+에서는 Graceful Shutdown을 설정으로 켤 수 있다.
# application.yml
server:
shutdown: graceful
spring:
lifecycle:
timeout-per-shutdown-phase: 30s
graceful로 설정하면 종료 신호를 받았을 때:
- 새 요청 수신 거부 (503 반환)
- 현재 처리 중인 요청이 완료될 때까지 대기 (최대 30초)
- 모두 완료되면 종료
SIGTERM 수신
│
├── 새 요청 → 503 (연결 거부)
├── 기존 요청 완료 대기 (최대 30초)
│
└── 완료 후 종료
로드밸런서 입장에서는 WAS가 503을 반환하기 시작하면 “비정상”으로 판단하고 해당 서버로의 트래픽을 끊는다.
해결 2: 로드밸런서 헬스체크 튜닝
헬스체크 간격을 줄이고, 서버가 빠르게 제외되도록 설정한다. (클라우드 로드밸런서마다 설정 위치가 다르지만 개념은 같다)
| 설정 | 변경 전 | 변경 후 |
|---|---|---|
| 헬스체크 간격 | 30초 | 5초 |
| 비정상 판단 기준 | 3회 연속 실패 | 2회 연속 실패 |
| 서버 제외까지 최대 | 90초 | 10초 |
헬스체크 간격 × 비정상 기준 횟수 = 서버 제외까지 최대 대기 시간이다. 이 시간 동안은 죽어가는 서버로 요청이 계속 날아간다.
Graceful Shutdown만으로는 부족한 이유
Graceful Shutdown을 켜면 WAS는 새 요청을 503으로 거부하기 시작한다. 하지만 로드밸런서가 503을 받고 WAS를 제외하기까지 헬스체크 주기만큼 시간이 걸린다. 그 사이에 날아오는 요청들은 WAS까지 도달해서 503을 받는다.
SIGTERM → WAS 새 요청 거부(503) → 로드밸런서 헬스체크 실패 감지 → WAS 제외
↑________________________________↑
이 구간이 문제
이 구간을 없애려면 Connection Draining(또는 Deregistration Delay) 설정이 필요하다. WAS가 제외 대상으로 표시되면, 로드밸런서가 기존 진행 중인 연결만 유지한 채 새 연결은 보내지 않는다.
배포 순서 (권장)
1. WAS-02 배포 신호
2. 로드밸런서에서 WAS-02 수동 제외 (또는 헬스체크 실패 대기)
3. WAS-02 Graceful Shutdown 시작 → 기존 요청 완료
4. WAS-02 종료 및 새 버전 기동
5. 헬스체크 통과 확인 후 로드밸런서에 WAS-02 다시 추가
6. WAS-01 동일하게 반복
Graceful Shutdown + 헬스체크 튜닝 + Connection Draining 세 가지가 함께 있어야 진짜 무중단 배포다.
배운 것
- Graceful Shutdown은 WAS가 천천히 죽게 하는 것이고, 로드밸런서 헬스체크는 빠르게 감지하는 것이다. 둘 다 없으면 502가 난다.
server.shutdown: graceful만 켜면 반쪽짜리다.timeout-per-shutdown-phase도 서비스 특성에 맞게 조정해야 한다.- 무중단 배포라고 불리려면 WAS, 로드밸런서, Connection Draining 세 레이어가 모두 맞아야 한다.
- 배포 직후 에러율 모니터링을 반드시 해야 한다. “롤링 배포 하면 무중단”은 설정을 안 잡으면 환상이다.