[우아한테크코스] 9월 2일 TIL

2 minute read

[infra] WAS vs 웹서버

https://www.ibm.com/cloud/learn/web-server-vs-application-server

웹서버는 static contents(HTML, 파일, 이미지, 비디오, Nginx 등등)를 전송한다.

WAS는 dynamic contents를 처리한다. 클라이언트와 서버 간의 상호 작용으로 요청에 따라 응답이 달라진다. Tomcat은 서블릿 컨테이너로 WAS에 포함된다.

우리가 돌리는 spring 프로젝트는 톰켓이 가져가서 돌리게 된다.

[Spring] 서블릿이란?

HTML에 자바를 사용해서 동적 데이터를 담고 싶어 나온 것으로 Java로 HTTP 요청과 응답을 처리하기 위한 표준이다

서블릿 표준은 인터페이스 이고, 구현은 Tomcat, Jetty, Undertow가 제공한다

Java로 http 요청과 응답을 주고받기 위해 존재한다

Jakarta servlet 공식문서

  • 서블릿 구조

image

그림과 같은디렉토리 구조로 서블릿을 만들어 war 파일로 배포한다.

정적 파일들(html, js)은 루트 디렉토리에, 컴파일된 서블릿 클래스는 /WEB_INF/classes에, 라이브러리 파일은 /WEB_INF/lib에 저장한다.

  • 웹서버와 서블릿의 관계

WebServer <-> Servlet Container

Controller <-> Servlet

AbstractController <-> HttpServlet

HttpRequest <-> HttpServletRequest

HttpResponse <-> HttpServletResponse

  • 서블릿 컨테이너의 일

    1. 통신 지원

    웹서버와 서블릿이 통신하도록 API 지원

    1. lifecycle 관리

    init, service, destroy (http server 구현시에 WebServer ~ RequestHandler)

    1. 멀티스레딩 지원

    새로운 요청이 들어오면 쓰레드 부여

  • 서블릿과 서블릿 컨테이너

    1. 사용자가 http 요청을 보낸다.

    image

    1. 요청을 받은 서블릿 컨테이너는 HttpServletRequest, HttpServletResponse 생성

    image

    1. 요청을 처리할 수 있는 서블릿을 찾아 스레드 할당하고 request, response 객체 전달

    image

    1. 서블릿 컨테이너는 service() 메서드를 호출하고 Http Method에 따라 doGet(), doPost()를 호출

    image

    1. 호출한 메서드에 따른 응답 객체 전달

참고

  • 서블릿 컨테이너의 멀티 스레딩

서블릿 컨테이너는 각 서블릿 객체를 하나씩 만들고 쓰레드를 부여하는 방식으로 사용한다. 이 경우 Request와 response를 지역 변수롤 객체에 선언해두면 thread safe하지 못할 수 있다.

따라서 스레드가 부여될 때마다 새로운 요청과 응답을 생성할 필요가 있다.

image

서블릿 컨테이너는 쓰레드풀을 만들어두고 제한된 스레드만 생성할 수 있도록 한다. 기본 값은 200이다.(maxThreads)

connectionTimeout도 걸려있기 때문에 요청이 쌓여서 기다리다가 이 시간이 지나버리면 timeout 에러가 발생하게 된다. (connectionTimeout)

요청이 쌓여서 기다리는 곳은 큐이다. 이 큐도 최댓값을 지나버리면 더 이상의 요청을 받아둘 수 없다. 기본 값은 100이다. (acceptCount)

server.tomcat.accept-count=100, server.tomcat.threads.max=200 과 같이 설정할 수 있다.

큐도 1, 스레드도 최대 1인 경우 2개 이상의 요청이 들어오면 큐에서 대기시킬 수도, 쓰레드에서 실행시킬 수도 없게 되어 문제가 발생할 수 있다 (tomcat8.5부터는 default로 Http11NioProtocol를 사용, maxConnection 까지 연결 수락하고 Poller가 관리하며 selector 라는 것을 이용해 번갈아가면서 processSocket을 실행하고 내부에고 exectuor가 Thread를 할당해 작업을 수행. 참고로 tomcat은 Thread pool의 backing queue를 사용하지 않음. jetty는 다름)

  • 서블릿 필터

필터는 요청이 들어오기 전에 하고싶은 처리를 할 때 사용한다.

  • From Data: 추가적인 메서드를 받게 한다거나

  • for log: 요청 전후로 로그를 찍는다거나

  • forwarded headers: 프록시를 통과 할 때 host, port를 클라이언트가 아닌 프록시로 전환할 수 있다.

  • Shallow ETag

  • CORS

참고

  • 필터 vs 인터셉터

필터는 DispatcherServlet 전에 필요한 작업을 수행하는데 인증, 로깅, 이미지 압축과 같이 스프링에 필요하지 않은 작업들을 수행한다.

인터셉터는 DispatcherServlet과 Controllers 사이에 필요한 작업을 수행하는데 디테일한 로깅, 인가 권한 체크, 스프링 컨텍스트, 모델 처리 등이 있다.