Spring Boot의 구조

민준·2025년 3월 3일
post-thumbnail

1. Tomcat + Spring 기본 구조

Spring MVC는 Tomcat 위에서 동작하는 구조

Tomcat + Spring 구조 = JRE(JVM) + Tomcat(Servlet) + Spring(Controller)

  1. Request (요청) : 클라이언트가 요청을 보내면 Request Queue에 적재됨

  2. Processing (처리) : Request Queue에서 하나씩 꺼내어 Spring이 처리

  3. Response (응답) : 처리 결과를 유저에게 반환

Spring Boot의 핵심 원리 = Request → Processing → Response

1.1. Tomcat + Spring 실제 동작 과정

1). Request (요청)

  • 클라이언트(사용자 또는 API 호출)가 요청을 보냄

  • Tomcat이 요청을 Connection Queue에 적재됨.

    • Connection(연결): 클라이언트와 서버 간의 TCP 연결을 의미.
  • Connection Queue에서 하나씩 Thread Pool에 요청을 할당하고 Catalina(Tomcat Engine)에게 전달.

Connection Queue와 Thread Pool

  • Tomcat 레벨의 Connection Queue: maxConnections 값으로 설정 (Tomcat이 동시에 처리할 수 있는 최대 클라이언트 연결 수)

  • maxConnections값이 초과 되면 추가요청은
    OS 레벨의 Connection Queue: acceptCount 값으로 관리 (대기 가능한 요청 개수)

  • acceptCount를 초과하면, 클라이언트는 "연결 거부(503 Service Unavailable)" 응답을 받을 수도 있음.

  • Tomcat Thread Pool:

    • maxThreads: 최대 스레드 개수

    • minSpareThreads: 최소한으로 유지되는 여유 스레드 개수

    • Tomcat은 ThreadPoolExecutor를 사용하여 다중 요청을 관리

2). Processing (처리)

  • Catalina(Tomcat Engine)가 요청을 받아 ServletRequest를 HttpServletRequest로 변환

  • Servlet Container는 요청을 적절한 Servlet을 찾아 요청을 넘김

  • Spring Boot에서는 DispatcherServlet이 Controller를 호출하여 모든 요청을 처리

DispatcherServlet이 하는 일

  • HandlerMapping → 적절한 Controller를 찾음

  • HandlerAdapter → Controller에게 요청을 넘겨줌

싱글톤(Singleton) 패턴의 활용

  • Servlet 객체는 싱글톤으로 존재하여 메모리를 절약하고 성능을 최적화

  • Spring Controller(Bean)도 싱글톤으로 관리되어 모든 요청을 하나의 객체에서 처리

  • 하지만 여러 개의 요청을 동시에 처리할 수 있도록, 각 요청은 별도의 스레드에서 실행됨

  • 각 스레드는 자신의 Method Stack에서 메서드를 실행하기 때문에 동시성과 격리성이 보장됨
    → Stateless & Thread-safe (상태를 가지지 않으면서도 안전하게 실행 가능)

3). Response (응답)

  • Controller가 응답을 처리하여 DispatcherServlet이 처리된 데이터를 받음

  • ViewResolver 또는 JSON 데이터로 변환

  • 최종적으로 클라이언트가 요청한 데이터 형식에 맞춰 View를 렌더링하여 클라이언트에게 HTML을 반환

1.2. Tomcat + Spring의 상세 구조

Spring Boot의 구조를 다음과 같이 Tomcat과 Spring 두 부분으로 나누어 설명

1.2.1. Tomcat (Servlet Container)

  • Tomcat은 Servlet Container 역할을 하며, 클라이언트의 요청을 받아 Spring의 DispatcherServlet으로 전달

  • 요청이 들어오면 Tomcat은 이를 하나의 스레드에 할당하고, DispatcherServlet이 적절한 컨트롤러를 호출하여 처리

"Connection = 1 요청 : 1 스레드"가 항상 맞는가?

  • 기본적으로 Tomcat은 "1 요청 = 1 스레드" 방식을 따름.
  • 하지만 NIO (Non-Blocking I/O) Connector가 설정된 경우에는 다르게 동작할 수 있음.
    • BIO (Blocking I/O, 기본 설정): "1 요청 = 1 스레드"가 성립.
    • NIO (Non-Blocking I/O): 하나의 스레드가 여러 요청을 처리할 수도 있음.

1.2.2. Spring (Spring Container)

  • Spring은 DispatcherServlet을 통해 요청을 컨트롤러로 전달하고, 비즈니스 로직을 수행한 후, 적절한 응답을 반환

Spring의 두 가지 ApplicationContext

Spring에서는 Bean을 관리하는 Spring Container가 있고, Spring Container를 크게 두 가지로 나눌 수 있음.

  1. Servlet WebApplicationContext

    • DispatcherServlet이 직접 사용하는 웹 관련 Bean들이 등록
    • 예: @Controller, HandlerMapping
    • 웹 요청을 처리하는 컨트롤러 및 필터 관련 Bean을 관리
  2. Root WebApplicationContext

    • 웹과 독립적으로 동작하는 서비스 계층, DAO 등을 관리
    • 예: @Service, @Repository
    • 비즈니스 로직과 데이터 처리를 담당

DispatcherServlet은 누구의 것인가?

DispatcherServlet은 Spring이 직접 구현한 Servlet 인터페이스의 구현체

  • Tomcat은 원래 Servlet 인터페이스를 기반으로 웹 애플리케이션을 실행

  • Spring은 이 Servlet 인터페이스를 확장하여 자체적으로 DispatcherServlet을 개발

즉, DispatcherServlet은 Spring 소속이지만, Tomcat의 Servlet 컨테이너에서 실행됨
이러한 관계를 이해하면 다음과 같은 개념을 명확히 알 수 있음

  1. Tomcat은 기본적으로 Servlet 기반의 컨테이너이며, 모든 요청을 Servlet을 통해 처리

  2. Spring은 DispatcherServlet이라는 자체 구현체를 제공하여 모든 웹 요청을 관리

  3. DispatcherServletController로 요청을 분배하는 핵심 역할을 수행하며,
    내부적으로 다양한 HandlerMapping, HandlerAdapter 등을 활용

0개의 댓글