ksundev 님의 블로그

[실무] Graceful Shutdown 본문

[개발] 개발지식+CS

[실무] Graceful Shutdown

ksundev 2025. 10. 19. 20:35

서버에서 Graceful Shutdown이란?

Graceful Shutdown의 개념

Graceful Shutdown은 서버를 안전하게 종료하는 방법입니다. 단순히 프로세스를 강제로 죽이는 것이 아니라, 진행 중인 작업을 완료하고 리소스를 정리한 후에 종료하는 것을 의미합니다.

비유하자면, 식당에서:

  • 강제 종료: 손님이 식사 중인데 갑자기 문을 닫고 불을 끄는 것
  • Graceful Shutdown: 신규 손님 받기를 중단하고, 현재 손님들이 식사를 마칠 때까지 기다린 후 문을 닫는 것

왜 필요한가?

일반적인 서버 종료의 문제점

서버를 강제로 종료하면 다음과 같은 문제가 발생합니다:

1. 사용자 경험 악화

사용자: "결제 버튼 눌렀는데 왜 응답이 없지?"
서버: (이미 죽음)
사용자: "돈은 빠져나갔는데 주문은 안 들어갔네?"

2. 데이터 손실 및 불일치

  • 데이터베이스 트랜잭션이 커밋되지 않고 중단
  • 파일 쓰기 작업이 중간에 끊김
  • 캐시와 DB 간의 데이터 불일치

3. 리소스 누수

  • 데이터베이스 연결이 제대로 닫히지 않음
  • 파일 핸들이 열린 채로 방치
  • 메모리나 네트워크 리소스가 정리되지 않음

4. 시스템 상태 불일치

  • 채팅 서버: 사용자가 여전히 온라인으로 표시됨
  • 세션 정보가 저장되지 않음
  • 진행 중이던 백그라운드 작업이 완료되지 않음

실제 발생 가능한 시나리오

시나리오 1: 전자상거래

1. 사용자가 결제 API 호출
2. 서버가 결제 처리 중
3. 개발자가 서버를 급하게 재시작 (강제 종료)
4. 결제는 완료되었지만 주문 DB에는 기록 안 됨
5. 결과: 환불 처리 및 고객 불만

시나리오 2: 채팅 서버

1. 1000명의 사용자가 WebSocket으로 연결 중
2. 서버 강제 종료
3. 모든 연결이 갑자기 끊김
4. 사용자들은 "왜 채팅이 안 되지?" 하며 혼란
5. 결과: 나쁜 사용자 경험

시나리오 3: 배포 중

1. 새 버전 배포를 위해 서버 재시작
2. 진행 중이던 API 요청 100개가 모두 실패
3. 사용자들에게 500 에러 발생
4. 결과: 순간적인 서비스 장애

Graceful Shutdown의 이점

1. 진행 중인 요청 완료

  • 현재 처리 중인 모든 요청이 끝날 때까지 대기
  • 사용자는 정상적인 응답을 받음

2. 데이터 무결성 보장

  • 트랜잭션이 완료되거나 안전하게 롤백
  • 파일 쓰기가 완료됨
  • 캐시와 DB 동기화

3. 리소스 정리

  • DB 연결 정상 종료
  • 파일 핸들 닫기
  • 메모리 해제

4. 무중단 배포 가능

  • 로드밸런서와 함께 사용하면 서비스 중단 없이 배포 가능
  • 헬스체크를 먼저 실패시켜 트래픽을 받지 않음
  • 기존 요청 처리 완료 후 종료

5. 상태 정리

  • 사용자 세션 정보 저장
  • 연결 상태를 정상적으로 업데이트
  • 백그라운드 작업 완료 또는 중단

Graceful Shutdown의 동작 과정

1. 종료 신호 수신 (SIGTERM, SIGINT 등)
   ↓
2. 새로운 요청 수락 중단
   ↓
3. 진행 중인 요청 완료 대기 (타임아웃 설정 가능)
   ↓
4. 리소스 정리
   - DB 연결 종료
   - 파일 닫기
   - 캐시 플러시
   ↓
5. 서버 종료

실무에서의 적용

Graceful Shutdown은 다음과 같은 상황에서 특히 중요합니다:

  • 배포 자동화: CI/CD 파이프라인에서 무중단 배포
  • 오토스케일링: 인스턴스 축소 시 안전한 종료
  • 서버 유지보수: 계획된 재시작이나 업데이트
  • 장애 대응: 문제 발생 시 안전한 복구

다음 시간에는 Go 기반 서버에서 Graceful Shutdown을 구현하는 방법에 대해 알아보겠습니다.