Graceful Shutdown in Go: HTTP 서버와 Kubernetes에서의 실용 패턴
AI Store에서 AI코딩으로 만들어진 앱을 만나보세요!
지금 바로 방문하기

Go 언어에서 Graceful Shutdown을 구현하는 실용적 패턴

분야

프로그래밍/소프트웨어 개발

대상자

Go 언어를 사용하는 개발자, HTTP 서버 및 컨테이너 환경(예: Kubernetes)에서 안정적인 종료 로직을 구현해야 하는 개발자, 리소스 관리 및 시스템 안정성에 관심 있는 개발자

핵심 요약

  • Go에서 우아한 종료는 신호 처리, 컨텍스트 기반 제어, 리소스 정리로 구성* **
  • os/signal 패키지로 SIGINT, SIGTERM 신호 처리, signal.NotifyContext로 컨텍스트 기반 종료 제어*
  • HTTP 서버 종료 시 Server.Shutdown()readiness probe 실패로 트래픽 차단, 30초 대기 후 종료*
  • defer로 리소스 정리, context.Context를 통해 모든 핸들러에 종료 신호 전파*

섹션별 세부 요약

  1. 신호 처리 및 컨텍스트 기반 종료 제어
  • os/signal 패키지로 SIGINT, SIGTERM 신호 직접 처리 가능
  • signal.NotifyContext를 사용해 컨텍스트 기반 종료 제어 구현 (Go 1.16 이상)
  • 버퍼링된 채널(용량 1) 사용으로 신호 유실 방지
  • context.WithTimeout으로 shutdown context에 타임아웃 설정
  • log.Fatal 대신 panic 사용 시 defer 내용 실행 가능
  1. HTTP 서버 및 컨테이너 환경 종료 처리
  • Server.Shutdown() 호출 전 readiness probe 실패로 트래픽 차단
  • Kubernetes 환경에서 terminationGracePeriodSeconds (기본 30초) 고려, 25초 이내 종료
  • readiness 핸들러에서 전역 변수로 종료 상태 판단, HTTP 503 반환
  • /healthz 엔드포인트로 상태 확인, 5초 대기 후 shutdown 수행
  • server.Shutdown 실패 시 강제 종료 fallback 처리
  1. 리소스 정리 및 시스템 안정성
  • 데이터베이스, 메시지 브로커, 캐시 등 외부 리소스 의도적 정리 필요
  • defer로 초기화 역순으로 종료 루틴 실행, 의존성 관리 용이
  • 메모리, 파일 디스크립터 등 OS 자동 정리 리소스 외 명시적 정리 필요 (예: 데이터 flush, 트랜잭션 rollback)
  • 로드밸런서 타겟 IP 업데이트 지연 시 트래픽 드레인 확인 필수
  1. 실무 팁 및 주의 사항
  • log.Fatal 사용 시 defer 실행 중단, panic으로 대체 권장
  • Prometheus /metrics 스크랩 시 마지막 메트릭 누락 가능성
  • systemd, nginx는 graceful shutdown 지원, Kubernetes/Docker는 지원 없음
  • 동일한 엔드포인트를 liveness/readiness로 사용하는 경우 주의
  • preStop 훅으로 15초 대기 시간 추가해 HTTP 503 비율 개선

결론

  • Go 애플리케이션의 우아한 종료는 신호 처리, 컨텍스트 기반 컨트롤, 리소스 정리로 구성* **
  • os/signal, signal.NotifyContext, context.Context 활용해 종료 신호 전파*
  • HTTP 서버 종료 시 readiness probe로 트래픽 차단 후 Server.Shutdown() 호출*
  • defer로 리소스 정리, context.WithTimeout로 타임아웃 설정*
  • Kubernetes 환경에서는 25초 이내 종료, preStop 훅으로 HTTP 503 개선*
  • log.Fatal 대신 panic 사용, 메트릭/로그 누락 방지*
  • 리소스 명시적 정리와 시스템 안정성 고려 필수*