스프링

Spring에서의 Servlet

꾸진 2022. 5. 30. 23:06

Servlet(서블릿)

  • Servlet이란?
    • 클라이언트의 요청(request)를 처리하고 이에 따라 처리 결과를 응답(response)을 보내주는 자바 웹 프로그래밍 기술입니다.
  • Servlet에서의 service() 메소드
    • HTTP 요청을 통해 매핑된 URL이 호출되면 Servlet Contatiner는 다음 메서드를 실행합니다.
    • protected void service(HttpServletRequest request, HttpServletResponse response)
    • 해당 메소드 실행을 통해 로직을 수행합니다.
  • Servlet 동작 과정
    1. 사용자가 URL을 클릭하면 HTTP Request를 Servlet Container에 보냅니다.
    2. Servlet Container는 HttpServletRequest, HttpServletResponse 두 객체를 생성합니다.
    3. 사용자가 요청한 URL을 분석하여 어느 서블릿에 대한 요청인지 찾습니다.
    4. 컨테이너는 서블릿의 service() 메소드를 호출하며, POST/GET 여부에 따라 doGet() 또는 doPost()가 호출됩니다.
    5. doGet() 이나 doPost() 메소드는 동적인 페이지를 생성한 후 HttpServletResponse 객체에 응답을 보냅니다.
    6. 응답이 완료되면 HttpServletRequest, HttpServletResponse 두 객체를 소멸시킵니다.
  • Servlet의 생명주기
    • init() - 서블릿이 처음으로 요청될 때 초기화를 하는 메서드
    • service() - 서블릿 컨테이너가 요청을 받고 응답을 내려줄 때 필요한 서블릿의 service 메서드
    • destroy() - 더 이상 사용되지 않는 서블릿 클래스는 주기적으로 서블릿 컨테이너가 destory() 메서드를 호출하여 제거

Servlet Container(서블릿 컨테이너)

  • Servlet Container(= Servlet을 지원하는 WAS)
    • 이러한 서블릿들은 서블릿 컨테이너 내에서 관리됩니다. 서블릿 컨테이너는 서블릿의 생성, 초기화, 호출, 소멸 등 생명주기를 관리합니다.
    • 이러한 서블릿 객체는 싱글톤으로 관리됩니다.
    • 매번 요청이 들어올 때마다 서블릿 객체를 생성해주게 되면 비 효율적이므로 싱글톤 객체를 생성할 수 있게 해줍니다.
    • 주의할 점은 싱글톤으로 사용하므로 공유 변수 사용에 주의해야합니다.
    • 동시 요청을 위한 멀티스레드 처리를 지원해줍니다.
    • 톰캣이 우리가 대표적으로 알고 있는 Servlet Container입니다.
  • 만약 Servlet Container가 없다면? (= Serlvet Container 사용 이유)
    • 개발자는 비즈니스 로직 구현 뿐만 아니라 클라이언트가 요청한 HttpMessage를 파싱하고 , 응답 메세지 생성해주는 부분을 직접 구현해야 할 것 입니다.
    • 아래 사진에서 비즈니스 로직 실행을 제외한 나머지 부분들 전부 서블릿 컨테이너가 지원해줍니다.

  • Question: 만약 100개의 요청이 동시에 오게되면 어떻게 처리할까?
    • 보통 하나의 요청에 하나의 스레드를 할당해주는데, 매번 요청이 올때마다 스레드를 생성해주는건 비효율적임.
      • 스레드 생성은 비용이 비싸기때문
      • 너무 많은 스레드가 생성이 된다면 CPU, 메모리 임계점을 초과해 서버가 죽을 수 있음
    • 따라서 Thread pool(스레드 풀)을 사용
    • 스레드를 미리 만들어놓고 만들어진 스레드를 가져다가 사용하는 방식
    • max pool size를 설정해줄 수 있는데, 만약 해당 사이즈를 초과해서 요청이 오게 되면 요청은 큐 형식으로 대기하거나 거절할 수 있음
  • Question: 그렇다면 스레드 풀을 어떻게 설정해야 최적일까?
    • 너무 크게 설정하게 되면 CPU, 메모리 임계점 초과가 발생할 수 있음
      • 동시 요청이 많으면, CPU, 메모리 리소스 임계점 초과로 서버 다운
    • 너무 낮게 설정하면 CPU의 성능을 제대로 사용하지 못하게 되는것
      • 동시 요청이 많으면, 서버 리소스는 여유롭지만, 클라이언트는 금방 응답 지연
    • 어플리케이션 로직의 복잡도, CPU 등 상황에 따라 다르므로 성능 테스트를 통해 최적을 찾아야함

Servlet Container와 Spring Container

  • Servlet Container
    • Servlet Container는 servlet의 생성부터 소멸까지의 일련의 과정(Life Cycle)을 관리합니다.
    • 서블릿 컨테이너는 요청이 들어올때마다 새로운 자바 스레드를 만듭니다.
    • 대부분의 웹프레임워크가 제공하는 기능은 서블릿 컨테이너 위에서 동작하는 서블릿, 필터, 이벤트 리스너 등을 적절하게 구현한 것입니다.
    • 따라서 사용자가 웹 프레임워크로 작성한 웹 애플리케이션은 결국 서블릿 컨테이너 위에서 동작합니다.
  • Spring Container
    • Spring Container는 Bean의 생명주기를 관리
    • Spring Container 종류에는 BeanFactory와 이를 상속한 ApplicationContext가 존재
      • BeanFactory: 스프링 컨테이너의 최상위 인터페이스임. 스프링 빈을 관리하고 조회
      • ApplicationContext: BeanFactory의 기능을 모두 상속해 사용, + 부가 기능
      • Bean Factory를 직접 사용할 일은 거의 없고 부가 기능이 포함된 Application Context를 사용함

ServletContext vs ApplicationContext

  • Servlet Context
    • 서블릿 컨테이너(= 톰캣과 같은)가 실행되면, 웹 어플리케이션을 로드해주는데 웹 어플리케이션이 다 로드가 완료되면 서블릿 컨테이너가 Servlet Context를 최초에 만든 후 서버 메모리에 저장해 계속 사용합니다.
    • 그 후 init() 을 호출해 컨테이너를 초기화 시킵니다
    • Servlet 단위로 생성되는 context
    • URL설정이 있는 Bean을 생성 (@Controller, Interceptor)
  • Application Context
    • Web Application 최상단에 위치하고 있는 Context
    • Spring에서 생성되는 빈에 대한 IoC Contatiner
    • 특정 Servlet설정과 관계 없는 설정을 한다 (@Service, @Repository, @Configuration, @Component)

Spring Boot에서의 Dispatcher Servlet

  • Spring Boot에는 임베디드 톰캣을 가지고 있기때문에 스프링 부트가 실행되면 임베디드 톰캣(= 서블릿 컨테이너)가 실행됩니다.
  • Spring Boot 실행 후 Dispatcher Servlet은 스프링 빈으로 등록되어 집니다.
  • Spring Boot에서 사용되는 서블릿은 Dispatch Servlet입니다.
  • Controller의 매핑을 담당합니다. (Front Controller)

출처:

18. Web MVC framework

ServletContainer와 SpringContainer는 무엇이 다른가?