Skip to main content

Command Palette

Search for a command to run...

Spring Boot에서 Graceful Shutdown이 필요한 이유와 기본 설정이 꺼져 있는 이유

Updated
•3 min read•View as Markdown

“Graceful Shutdown” 이란?

서비스를 운영하다 보면 서버를 재시작하거나 배포할 때 요청이 끊기는 문제가 생길 수 있습니다.

Graceful Shutdown은 서버가 종료될 때 처리 중인 요청을 안전하게 마무리하고, 리소스를 정리한 후 종료하는 방식을 말합니다.

일반적인 Immediate Shutdown(즉시 종료)과 달리, 현재 진행 중인 트랜잭션과 연결을 끝까지 처리해 데이터 정합성을 유지할 수 있습니다.


왜 필요한가?

1️⃣ 처리 중인 요청 손실 방지

서버가 중간에 꺼지면 응답을 못 받은 클라이언트는 실패로 인식하지만, 서버 쪽에서는 이미 데이터가 반영될 수 있습니다. → 중복 처리, 데이터 불일치 발생

2️⃣ 트랜잭션 안정성 확보

DB 트랜잭션이 열린 상태에서 강제 종료되면 커밋/롤백이 정상적으로 이루어지지 않아 정합성 문제가 생깁니다.

3️⃣ 리소스 정리

DB 커넥션, 메시지 큐 연결, 파일 핸들러 등을 정상적으로 닫아야 리소스 누수와 락(Lock)을 방지할 수 있습니다.

4️⃣ 클라우드 환경에서 필수

Kubernetes, AWS Auto Scaling 등에서 인스턴스 교체 시 Graceful Shutdown이 없으면 Rolling Update 중 요청이 끊기고 서비스 장애가 발생할 수 있습니다.


Spring Boot에서 기본 동작

  • 기본값: Immediate Shutdown (즉시 종료)

  • 서버가 SIGTERM 신호를 받으면 새로운 요청을 차단하고, 현재 처리 중인 요청과 관계없이 바로 프로세스를 종료합니다.|

    SIGTERM 수신 시

    1. 더 이상 요청을 받지 않음 (서버 소켓 닫힘)

    2. 현재 처리 중인 요청 무시하고 즉시 프로세스 종료

    3. 커넥션 풀, 스레드 풀 강제 종료

➡️ 이 상태라면 긴 처리 요청 중간에 서버가 내려가면 데이터 손실, 트랜잭션 중단, 요청 실패가 발생할 수 있습니다.

SIGTERM vs SIGKILL 차이

  • SIGKILL: 프로세스를 강제로 종료, 핸들링 불가

  • SIGTERM: 프로세스가 시그널을 받아 종료 절차를 안전하게 수행 가능

  • Graceful Shutdown은 SIGTERM을 활용하고, SIGKILL은 Graceful Shutdown이 불가능하다.


Spring Boot에서 Graceful Shutdown 활성화하기

Spring Boot 2.3 이상부터는 설정 한 줄로 Graceful Shutdown을 켤 수 있습니다.


server:
  shutdown: graceful
spring:
  lifecycle:
    timeout-per-shutdown-phase: 30s  # 요청 완료 대기 최대 시간 (기본값 30s)

➡️ 새로운 요청은 차단하고, 현재 처리 중인 요청이 완료될 때까지 최대 30초 대기 후 종료.


그럼 왜 기본값이 "꺼져" 있을까?

라는 의문이 들 텐데요,

"Graceful Shutdown이 이렇게 중요한데, 왜 Spring Boot는 기본으로 안 켜놨을까?"

1. 빠른 종료 우선

초기 Spring Boot는 WAS(Tomcat)의 기본 정책을 따라 즉시 종료를 기본값으로 유지했습니다. 테스트나 간단한 앱에서는 빠르게 종료되는 것이 더 중요했기 때문입니다.

2. 항상 안전한 것은 아님

Graceful Shutdown은 요청 완료를 기다리는 동안 서버가 종료되지 않고 남아 있을 수 있습니다. 요청이 오래 걸리는 서비스라면 오히려 종료가 지연될 수 있어 환경에 따라 부작용이 발생할 수 있습니다.

3. 환경별 요구사항 다름

Kubernetes, ECS, 온프레미스 등 배포 환경마다 종료 시그널 처리 방식이 다르기 때문에, Spring은 개발자가 의도적으로 설정을 켜는 것을 권장합니다.


결론

  • Graceful Shutdown은 안정적인 서비스 종료를 위해 꼭 필요한 기능

  • Spring Boot는 2.3 이상에서 옵션으로 지원하며, 명시적으로 켜야 함

  • 클라우드 환경, 트랜잭션 무결성이 중요한 서비스에서는 필수 설정


한 줄 요약

Graceful Shutdown은 요청 손실과 데이터 불일치를 막는 안전장치이며, Spring Boot에서는 기본 꺼져 있으니 server.shutdown=graceful 로 명시적으로 켜는 것이 좋다.

More from this blog

낙관적 락(Optimistic Lock)과 비관적 락(Pessimistic Lock)

락(Lock)의 필요성 현대 애플리케이션은 대부분 동시성(Concurrency) 문제에 직면합니다. 여러 사용자나 프로세스가 동시에 같은 데이터를 수정하거나, 은행 계좌 이체와 같은 중요한 트랙잭션을 동시에 실행하는 경우가 있습니다. 이때 동시 접근을 적절히 제어하지 않으면, 데이터 불일치, 중복 처리, 시스템 오류까지 발생할 수 있습니다. 이를 방지하기 위해 락(Lock) 개념이 도입되었습니다. 락은 여러 프로세스나 스레드가 동시에 동일한 자...

Aug 22, 20253 min read

Java 프로그램이 실행되는 흐름

자바 프로그램은 단순히 .java 파일을 실행하는 것이 아니라, 컴파일 → 로드 → 실행 이라는 여러 단계를 거쳐 최종적으로 CPU 가 이해할 수 있는 기계어로 변환됩니다. 이 과정에서 JDK, JVM, JRE가 각각 어떤 역할을 하는지 이해하는 것이 중요합니다. 1. 소스 코드 작성과 컴파일 개발자는 자바 소스 파일(.java)을 작성 JDK 에 포함된 javac (Java Compiler)가 소스 코드를 컴파일 하여 JVM이 이해할 수...

Aug 21, 20252 min read

Java Collection Framework

컬렉션 프레임워크(Collection Framework)란? 자바에서 컬렉션 프레임워크란 다수의 데이터를 쉽고 효과적으로 처리할 수 있는 표준화된 방법을 제공하는 클래스와 인터페이스 집합입니다. 즉, 데이터를 저장하는 자료구조과 데이터를 처리하는 알고리즘을 구조화하여 클래스로 구현한 것입니다. 모든 컬렉션 프레임워크는 자바의 인터페이스를 기반으로 구현됩니다. JFC(Java Collection Framework)의 도입 배경 JCF 이전에는 ...

Aug 14, 20254 min read

운영체제의 발전: 단일 프로세스에서 멀티코어까지

운영체제의 발전은 ‘CPU를 얼마나 효율적으로 활용하느냐’의 역사라고 볼 수 있습니다. 초기에는 한 번에 하나의 프로그램만 실행했지만, 점차 CPU 사용률과 사용자 경험을 높이기 위해 멀티프로그래밍, 멀티태스킹, 멀티프로세스, 멀티스레딩, 그리고 멀티코어 구조가 발전했습니다. 들어가기에 앞서 프로세스와 스레드에 대해 간단히 설명하겠습니다. 프로세스(Process) 실행 중인 프로그램으로 OS로부터 독립된 주소 공간과 자원을 할당 받음 각 ...

Aug 13, 20252 min read

Keep-Alive (HTTP Keep-Alive와 TCP Keep-Alive)

Keep-Alive는 연결(Connection)을 계속 유지하기 위한 메커니즘입니다. 네트워크에서 어떤 연결을 만들고, 요청/응답을 주고받은 후 바로 끊지 않고 일정 시간 동안 유지하면, 그 시간 안에 들어오는 추가 요청은 이미 열린 연결을 재사용할 수 있습니다. 이를 통해 매번 연결을 새로 맺는데 필요한 오버헤드(3-Way Handshake)를 줄일 수 있고, 불필요한 지연(latency)를 감소시킬 수 있습니다. 하지만 연결을 너무 오래 유...

Aug 12, 20252 min read

gaeng

22 posts