이번 게시글에선 WAS가 어떻게 실행되고, 요청을 처리하는지 알아보겠습니다.

또한, 그 과정에서 WAS에 배포된 Spring 프로젝트를 어떻게 구동시키는지도 함께 알아보시죠,,

WAS가 뭐야? - Tomcat…

  • 우리는 면접 단골 문제로 web server와 web application server의 차이점에 대해서 외운 적이 분명히 있습니다..
    • web server는 정적 컨텐츠를 다루고, web application server는 동적 컨텐츠를 다룬다고 말이죠..
  • 그 후, 실무에서 WAS를 접할 땐 종종 이런식으로 접하게 됩니다.
    • WAS 그거 스프링 서버 아냐?
    • 톰캣? 아~ 그 고양이 그림~?
    • 톰캣이 스프링 아니야?
      • 응 아냐…
  • 톰캣과 스프링은 분명 다른데 어디까지고 톰캣이고 스프링인지, 또한 각자의 구분되는 역할이 무엇인지, 항상 grey zone 어딘가에 흐릿하게 있었던 것 같습니다..
  • 이번 기회에 톰캣과 스프링의 내부를 분석하여, 그 둘의 요소와 각각의 역할에 대해서 자세하게 알아볼까요?
    • 더 이상 상자 안의 고양이 는 nomore…

 

그림 그리는 게 젤 오래 걸리네여..

WAS 내부 구조

WAS의 내부 구조는 위의 그림과 같이 표현해볼 수 있습니다.

  • 톰캣 관련 사양
    • 설정 파일
      • server.xml
      • web.xml
    • 커넥터(Connector - Coyote)
    • 쓰레드풀(ThreadPool)
    • 서블릿 컨테이너(Servlet Container - Catalina)
  • 스프링 관련 사양 - 그림에서 초록색으로 색칠된 부분
    • 설정파일
      • root-context.xml
      • servlet-context.xml
    • 컨텍스트 로더 리스너 (ContextLoaderListener)
    • 디스패처 서블릿 (DispatcherServlet)
    • 스프링 컨테이너(Spring Container)

 

WAS 초기화 단계 VS Client 요청 처리 단계

  • 웹서버 초기화 단계
  • 클라이언트 요청 처리 단계
  • 톰캣과 스프링에 대해 내부적으로 자세히 알아보기 위의 두가지 단계로 구분지어 살펴보겠습니다.
    • 이번 게시물에선 1번 항목인 WebServet 초기화 단계까지 알아볼게요~

 

WAS 초기화 단계

 

1. 톰캣은 먼저 server.xml을 읽어서 커넥터와 쓰레드풀을 초기화 시킴

  • 톰캣이 실행되면, 톰캣은 초기화를 위한 설정 파일들을 읽습니다.
  • 그 중에서 server.xml이란 설정파일을 읽어서 커넥터와 쓰레드 풀을 생성시킵니다.

 

커넥터란?

  • 커넥터는 클라이언트의 요청을 받고 쓰레드풀에서 쓰레드를 가져온 다음, 서블릿 컨테이너에 요청을 전달합니다.
  • 우리가 비교적 익숙하게 본 적 있는 Request, Response 객체가 이 영역에서 생성됩니다.
    Http 정보 파싱 또한 이곳에서 이루어집니다.
  • 톰캣의 기본 커넥터는 Coyote입니다..!
org.apache.coyote.AbstractProcessor에서 Request, Response 인스턴스가 생성됨을 확인!

 

쓰레드 풀이란?

  • 요청이 들어왔을 때, 쓰레드를 즉시 할당시키기 위해 쓰레드 풀을 미리 생성시키는 것입니다.

 

 

2. 다음으로 web.xml을 읽어서 서블릿 컨테이너를 초기화

  • server.xml을 읽고 커넥터와 쓰레드풀을 초기화하였다면
  • 그 다음으로는 web.xml을 읽고 서블릿 컨테이너를 초기화할 차례입니다.
  • 서블릿 컨테이너를 초기화 시킬 때 주목해야할 부분은 ContextLoaderListener와 DispatcherSerlvet입니다.

 

ContextLoaderListener

  • 톰캣은 web.xml을 읽고 ContextLoaderListener를 초기화합니다.
  • ContextLoaderListener는 스프링 컨테이너를 구성하고 초기화하는 객체 중 하나입니다.
    • ContextLoaderListener는 root-context.xml을 읽고 Root WebApplicationContext를 초기화합니다.
    • ContextLoaderListener는 보통 스프링 시큐리티, Service레이어, Repository레이어를 구성합니다.
    • 보통 스프링 시큐리티를 이곳에 구성하는 이유는 전체 애플리케이션에 대한 보안 설정을 할 수 있기 때문입니다.
      • Servlet WebApplicationContext에 스프링 시큐리티를 구성하면 서플릿에 대한 필터에만 적용됩니다.

 

DispatcherServlet

  • 스프링을 공부하다보면 많이 보이게 되는 디스패처 서블릿이 여기에 등장합니다..!
  • ContextLoaderListener를 통한 초기화 이후, 톰캣은 같은 설정파일인 web.xml을 통해 DispatcherSerlvet을 초기화합니다.
  • 초기화단계에서 DispathcerServlet은 servlet-context.xml을 읽고 Servlet WebApplicationContext를 초기화합니다.
  • Sevlet WebApplicationContext에는 HandlerMapping, HandlerIntercepter, HandlerAdapter, HandlerExceptionResolver 등 요청을 처리하는데 필요한 객체들과 개발자가 작성한 Controller들이 구성됩니다.

 

정리 - 헷갈릴 수도 있는 사항 주의!

  • 이번 게시물은 톰캣 실행 시, 톰캣과 스프링에 대한 각각의 사양이 어떻게 초기화되는지 알아보았습니다.
  • 다음 게시물에선 클라이언트에서 요청을 보냈을 경우, 위의 설명을 토대로 내부적으로 어떠한 방식과 순서로 처리되는지 알아볼게요!
  • 마지막으로 블로그글을 작성하면서 이 부분은 헷갈릴수도 있겠다 라는 사항들을 정리해보았습니다! 자료조사하는데 이부분을 구분안하고 잘못작성된 글들이 꽤나 많더라구요..
    • Servlet Container != Spring Container
    • 톰캣 쓰레드풀 != DB 커넥션풀
    • 쓰레드 != 싱글턴, 서블릿 == 싱글턴, 스프링빈 == 싱글턴