Spring - Servlet Container와 Servlet

Spring이 HTTP 요청을 받아들이고 처리하는 핵심 요소인 Servlet Container란 무엇인지 알아보자.

WAS

Servlet Container는 Spring에서 WAS(Web Application Server, 웹 어플리케이션 서버)의 역할을 담당한다. 그렇다면 WAS란 무엇일까?

WAS는 쉽게 말해서 동적인 컨텐츠를 처리하는 서버이다. 대게 클라이언트의 요청을 처리하는 서버는 웹서버와 WAS로 나누어 볼 수 있다.(물론 대규모 아키텍쳐에서는 더 세분화하여 나누어진다) 웹서버는 웹 어플리케이션 서버의 앞단에서 요청을 먼저 받아 정적인 컨텐츠에 대한 요청을 처리하고 동적컨텐츠 요청인 경우 WAS로 요청처리를 넘긴다. 이러한 역할 분리 외에도 웹 서버와 WAS로 분할 운용함으로써 얻을 수 있는 이점들이 여러 존재한다.

  • 데이터 캐싱 - 이전 요청을 캐싱해 빠른 응답처리
  • WAS로의 직접 접근 제한 - 클라이언트로부터 WAS의 존재를 가림
  • WAS 헬스체크 - WAS로 헬스체크 통해 운용 문제 체크 가능
  • WAS로의 로드밸런싱 - 트래픽이 몰리면 연결된 다수의 WAS로 트래픽 분할

web_was
웹서버와 WAS


하지만 대부분의 사이드 프로젝트에서 두 서버를 나누어 배포하지는 않는다. 큰 트랙픽이 나오지 않을 뿐더러 WAS가 보통 웹서버의 기능을 내장하고 있어 WAS만 해보하는 경우가 많다. WAS에는 요청을 동적으로 처리하기 위한 여러 비즈니스 로직들이 들어간다. 우리가 작성한 Java 코드가 그러한 것들이다.



Servlet Container

WAS. 즉, 요청을 처리하는 프로그램으로써 동작하기 위해 Servlet Container는 여러가지 기능을 가지고 있다.

  • 웹 어플리케이션의 생명주기 관리
  • 요청처리 객체인 Servlet의 생명주기 관리
  • 요청과 Servlet 매핑
  • 스레드 풀 관리

어플리케이션이 원활하게 동작하기 위한 환경을 구축해 준다고 볼 수 있다. 요청을 처리가능한 객체에게 넘겨주며, 대규모 트래픽을 빠르게 처리하기 위해 스레드 풀을 관리한다. 이러한 Servlet Container의 역할을 담당하는 프로그램들에는 Tomcat, Jetty, JBoss 등이 존재한다.


WAS의 멀티스레드 처리방식

Spring이 멀티스레드를 이용히여 요청을 처리한다는건 잘 알려진 사실이다. 하지만 우리가 개발을 하면서 스레드를 생성하는 일은 거의 존재하지 않는다. 우리는 마치 싱글 쓰레드를 사용하는 것처럼 프로그래밍을 하면 된다. 어떻게 가능한것인가?

이는 Servlet Container가 처리해주기 때문이다. 요청이 들어오면 요청마다 다른 쓰레드를 배정한다. 즉, 알아서 멀티스레드 방식으로 동작한다는 것이다. 덕분에 개발자들은 편리하게 코드를 작성할 수 있다. 하지만 주의할 점이 있다. Servlet과 Bean들은 싱글통 객체이므로 멀티 쓰레드 환경에서 주의해서 사용해야한다. 상태가 존재한다면 예상치 못한 문제가 발생할 수 있다.

또한 Servlet Container는 멀티스레드 환경에서 요청을 효율적으로 처리하기 위해서 스레드 풀 방식과 스레드 지연 방식을 이용한다.

💡 스레드 풀
요청을 받았을때 스레드를 동적으로 생성하고 삭제하는 방식이 아닌 미리 스레드를 쓰레드 풀에 보관하고 사용하는 방식이다. 스레드를 생성하고 삭제하는 비용은 크기 때문에 프로그램 구동시 미리 스레드를 만들어 놓고 이를 재사용한다.
또한 얼마나 많은 스레드를 만들어 놓을 것인가는 프로그램 전체의 성능을 좌우하기 때문에 스레드 풀에 존재하는 스레드 수를 적절하게 조절하는 것이 중요하다.

💡 스레드 지연
과도한 요청이 들어오면 요청을 대기시키고 스레드 풀을 동적으로 조절한다.

만약 프로그래밍 도중 상태가 필요한 경우에는 어떻게 해야할까? 이를 위해 스레드 동기화 기법이 존재한다. 대표적으로 synchronized 키워드 이용, lock 객체 사용, Thread-safe한 자료구조 사용, 혹은 스레드가 자체적인 데이터를 유지하며 동시에 다른 스레드가 독립적으로 작업을 수행할 수 있는 스레드 로컬을 이용할 수도 있다.


왜 Tomcat인가

앞서 살펴보았듯 WAS에는 여러 종류가 존재한다. 하지만 대부분의 프로젝트에서 Tomcat을 이용하는데 왜 그럴까? Tomcat의 장점은 다음과 같다.

  1. 경량
    WAS로 동작하는데 필요한 기능만을 가지고 있다.
  2. 안정성과 신뢰성
    오픈소스로써 이미 검증되어 있으며 지속적으로 개선이 이루어지고 있어 신뢰성과 안정성을 동시에 가지고 있다.
  3. 확장성과 유연성
    만약 기능이 더 필요하다면 다른 모듈을 이용할 수도 있고 다른 WAS들과 함께 실행이 가능하다.


여러가지 Servlet들

많이 사용되는 Servlet들은 다음과 같다.

Default Servlet
어플리케이션에서 정적인 리소스에 대한 처리를 담당한다. 웹 서버와 밀접하게 연결되어 정적인 리소스의 요청을 처리하고 응답을 반환하는 역하을 한다. 만약 요청에 대한 리소스가 없다면 404 에러를 반환한다.
서블릿 컨테이너에 내장되어 있어 별도의 구현이 필요하지 않는다.

DispatchServlet
어플리케이션에서 동적인 요청을 처리한다. Front Controller 패턴을 사용하여 동적인 요청에 대한 공통 로직을 처리 후 알맞은 핸들러를 찾아 요청을 보낸다.

Filter
요청 및 응답을 가로채 변형 및 특정 작업을 수행한다. 다른 서블릿으로 가기전 가장 먼저 요청을 받아 필터링하며 필터는 여러개 둘 수 있다.(필터 체인)
공통된 보안 및 인증 관련 작업, 요청 로깅, 이미지/데이터 압축 등 Spring Container와 분리되어야 하는 기능들을 담당한다.

카테고리:

업데이트:

댓글남기기