개발/Spring & Spring Boot

초기 세팅시 스프링부트 메인을 실행했는데 꺼지는 이유

copcat 2025. 4. 10. 16:47

스프링부트(Spring Boot) 프로젝트를 새로 세팅하고, Application 클래스를 실행해보면 8080 포트에서 서버가 실행되기를 기대하게 됩니다. 별다른 에러 없이 애플리케이션이 곧바로 종료되는 경험을 한 적이 있으신가요?

 

이번 글에서는 Spring Boot가 자동으로 종료되는 이유톰캣(Tomcat) 서버가 JVM을 유지시키는 메커니즘, 그리고 Non-Daemon Thread의 역할에 대해 간단하게 정리해보겠습니다.

 

1. Spring Boot 애플리케이션이 곧바로 종료되는 이유는?

Spring Boot는 실행 시 프로젝트에 포함된 의존성 등을 바탕으로 애플리케이션이 Web 환경인지, Non-Web 환경인지 자동으로 판단합니다.

 

예를 들어 다음과 같은 경우에는 Spring Boot는 Web 환경이 아니라고 판단합니다

 

  • spring-boot-starter-web 또는 spring-boot-starter-webflux가 포함되어 있지 않음
  • 유지되어야 할 백그라운드 서비스가 없음

 

하지만 중요한 포인트는 이것입니다

Spring Boot 애플리케이션이 종료되는 직접적인 원인은 Web 환경이 아님이 아니라, JVM 내에 Non-Daemon Thread가 존재하지 않기 때문입니다.

 

즉, Web 여부가 아닌 Thread의 상태가 애플리케이션 생존을 결정합니다.

 

 

2. JVM과 Non-Daemon Thread란?

 

JVM(Java Virtual Machine)은 내부에 실행 중인 모든 Non-Daemon Thread가 종료되었을 때, 전체 애플리케이션을 종료시킵니다.

 

  • Daemon Thread: 백그라운드에서 동작, JVM이 자동 종료되어도 함께 종료됨 (예: GC, Timer)
  • Non-Daemon Thread: 주요 작업을 수행, 하나라도 살아있으면 JVM은 종료되지 않음

 

즉, 스프링부트 애플리케이션이 자동 종료되었다는 것은 Non-Daemon Thread가 존재하지 않았다는 의미입니다.

 

 

3. 톰캣이 JVM을 종료되지 않게 막는 방식은?

 

Spring Boot는 spring-boot-starter-web 의존성을 통해 톰캣(Tomcat) 웹서버를 내장합니다.

톰캣은 내부적으로 Non-Daemon Thread, 특히 main thread 역할을 하는 ‘Acceptor’, ‘Poller’, ‘Executor’ 등을 통해 HTTP 요청을 수신하고 처리합니다.

 

이러한 쓰레드가 동작함으로써 JVM이 종료되지 않으며, SpringApplication.run(…) 이후에도 애플리케이션이 계속 살아있는 이유가 됩니다.

 

 

4. 예제로 보는 Non-Daemon Thread

 

톰캣을 포함하지 않은 순수 Spring Boot 프로젝트에서는 다음과 같이 Non-Daemon Thread를 명시적으로 생성하면 JVM을 종료시키지 않을 수 있습니다:

 

public class NonDaemonThreadTest {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            try {
                Thread.sleep(100000); // 100초 동안 대기
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        thread.setDaemon(false); // 명시적으로 Non-Daemon 설정
        thread.start();
    }
}

위 코드는 메인 메서드가 종료된 이후에도 Non-Daemon Thread가 살아 있으므로, JVM은 종료되지 않습니다.

 

 

5. 결론 및 요약

  • Spring Boot 애플리케이션이 자동 종료되는 이유는 Non-Daemon Thread가 없기 때문입니다.
  • 톰캣은 Non-Daemon Thread를 실행하여 JVM이 종료되지 않도록 합니다.
  • Web 서버가 포함되지 않은 프로젝트에서는 JVM이 실행과 동시에 종료될 수 있습니다.
  • JVM의 종료 조건을 이해하면, 백그라운드 작업 처리나 커스텀 런타임 애플리케이션 설계에 도움이 됩니다.

 

반응형