Spring boot와 내장 Tomcat 그리고 서블릿 전체적인 구조

lsy·2022년 11월 8일
2

서블릿

서블릿은 자바 진영의 웹 어플리케이션 프로그래밍 기술이다. 말이 너무 추상적인데, 동적 웹페이지를 만드는 코드를 작성 또는 로직을 구현한 클래스를 서블릿 클래스라고 부른다.

서블릿 클래스는 HttpServlet클래스를 상속받아 구현해야 하고, doGet메서드와 doPost메서드를 둘 다 구현해야한다. 이후 web.xml에 해당 클래스를 각 요청에 맞게 매핑해야한다.

예를 들어 /hello로 들어오는 요청을 HelloServlet클래스가 담당하기로 했다면, 둘을 해당 xml에 매칭시켜줘야 서블릿 컨테이너(WAS)가 인식한다.

public class HundredServlet extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
    int total = 0;
    for (int cnt = 1; cnt < 101; cnt++)
      total += cnt;
    PrintWriter out = response.getWriter();
    out.println(<HTML>);
    out.println(<HEAD><TITLE>Hundred Servlet</TITLE></HEAD>);
    out.println(<BODY>);
    out.printf(1 + 2 + 3 + ... + 100 = %d ”, total);
    out.println(</BODY>);
    out.println(</HTML>);
  }
}

대략 이런 느낌이다.

이렇게 만든 서블릿 클래스는 Tomcat같은 서블릿 컨테이너(WAS)가 관리하며 클라이언트에서 받은 요청에 따라 web.xml을 스캔해서 해당하는 요청에 맞는 서블릿을 실행시켜 웹페이지를 생성후 돌려준다.

Tomcat은 자바 구현체다. 실제로 Spring boot 프로젝트에서 Tomcat 클래스를 통해 객체를 생성할 수 있다.

WAS, WS

WAS는 Web-Application Server로 동적인 컨텐츠 처리를 담당한다. 즉 무언가 로직 처리를 담당한다. DB를 접근해야 한다거나 그런 행위를 처리한다. Tomcat같은 것이 있다.

WS는 Web-Server로 정적인 컨텐츠 처리를 담당한다. 로직 처리 없이 그냥 들어온 요청에 대해 올바른 컨텐츠(html, css 등)를 응답하면 될 때 사용한다. Apache같은 것이 있다.

보통 성능상의 문제로 두 개를 나누어서 쓴다고 하는데 많이들 알려져 있는 정석적인 구조는 다음 그림과 같다.

그런데 사실 WAS는 WS의 기능도 가능하다. 성능상의 문제도 없다고 한다. 그래서 요즘은 굳이 두 개를 나누지 않고 WAS 하나가 전부 처리한다고 한다. 대표적으로 Tomcat이 해당 역할을 전부 수행한다.

그림에서 컨테이너에 해당하는 부분이 바로 서블릿 컨테이너라고 할 수 있겠다.

따라서 다른 기능이나 모듈을 같이 사용할 필요가 있을 경우나 로드 밸런싱이 필요한 경우 WS와 WAS를 따로 두어 사용한다고 한다.

Spring boot에서의 Tomcat

그렇다면 Spring Boot에 내장되어 있는 Tomcat은 어떤 구조로 사용되고 있는 것일까? 우선 Spring boot의 모든 처리는 프론트 컨트롤러인 DispatcherServlet이 담당하고 있다는 사실을 알 것이다. 해당 클래스 이름이 Servlet인 것처럼, DispatcherServletHttpServlet을 상속받은 구현체다. 즉 서블릿이란 소리다.

위 구조에서는 각 요청마다 서블릿을 하나씩 매핑했다. Spring boot에서는 이렇게 하지 않고 DispatcherServlet이라는 서블릿을 하나만 둔 다음 해당 서블릿이 각 요청을 Spring boot에서 개발자가 구현한 각 컨트롤러와 서비스에 매핑시켜 해당 구현체들이 로직을 처리하게 만드는 구조다.

즉 정리하면 spring boot는 다음과 같은 구조로 요청을 처리한다.

1. Spring boot가 실행되면서 내장 Tomcat을 실행하고, DispatcherServlet을 서블릿 컨테이너에 등록한다.
2. 클라이언트로부터 첫 요청시, 서블릿 초기화 작업이 일어난다. 아니라면 만들어둔 서블릿 인스턴스를 사용한다.
3. 이후 들어온 요청을 DispatcherServlet가 각 컨트롤러(핸들러)를 찾아서 매핑시켜주고, 각 컨트롤러는 개발자가 구현한 로직에 따라 코드를 처리 후 View나(일반적인 Spring MVC) http 응답(@ResponseEntity@RestController의 경우)을 DispatcherServlet에게 돌려준다.
4. WS를 통해 클라이언트에게 응답한다.

이 과정은 Spring boot 프로젝트를 실행하면 자동으로 일어난다. 빨간색으로 칠한 부분, Controller와 Service, 그리고 그림에는 그리지 않았지만 DB에 대한 모델, Repository 등을 구현하는 것이 바로 개발자가 하는 일이다.

과정을 매우 생략해서 그렸지만, 사실은 DispatcherServlet이 해당 핸들러를 찾는 과정과 클라이언트에게 응답하는 과정중에 많은 일이 일어난다. 따로 시간되면 포스팅해야겠다. 또는 구글에 DispatcherServlet 동작 과정에 대해 많은 레퍼런스들이 있으니 참고하면 될 것 같다.

서블릿에 관한 자세한 내용은 https://wrkbr.tistory.com/520 여기를 참조하면 더 도움이 될 것 같다.


Reference

https://makemethink.tistory.com/169
https://jj-yi.tistory.com/36

profile
server를 공부하고 있습니다.

0개의 댓글