JSP와 Servlet 비교

서블릿(servlet)은 서버에서 웹페이지 등을 동적으로 생성하거나 데이터 처리를 수행하기 위해 자바로 작성된 프로그램이다. servlet은 Java코드 안에 HTML 태그가 삽입되며 자바언어로 되어 있다.

  • .java가 확장자이다.

  • 서블릿(servlet)은 자바언어를 웹어플리케이션에 조금 더 개발하기 쉽게 하기 위해 만든 API들이며 이 규약에 맞는 라이브러리나 클래스들을 상속 및 구현하여 만든 클래스들을 서블릿이라고 한다. HttpServlet 클래스를 상속받는다.

서블릿 기반 스크립트 기술이 JSP(Java Server Pages)이다.

-> HTML 내부에 Java 코드를 삽입하는 형식으로 개선한 것이 JSP이다.

서블릿만 사용하여 사용자가 요청한 웹 페이지를 보여주려면 println 메소드를 사용하여 html 문서를 작성해야 하는데, 서블릿은 데이터의 입력, 수정 등에 대한 제어를 JSP에게 넘겨서 프레젠테이션 로직을 수행한 후 컨테이너에게 response를 전달한다.

위 페이지의 경우, <ul>태그 안에 <li>태그를 <c:forEach>태그로 동적 생성한 코드이다. 하지만 결국 우리가 브라우저로 볼 수 있는 결과물 html에서는 JSTL문법의 흔적 없이 순수한 <li>들 만을 볼 수 있다.

JSP의 작동 원리는 다음과 같다. 이전 포스팅에서 Web Server와 WAS의 개념을 보고 오면 이해가 빠를 것이다.

  1. Web Server로 JSP 요청이 들어온다.

  2. WAS는 JSP에 관한 Servlet을 메모리에 올리고 쓰레드를 생성한다.

  3. 해당 쓰레드에서 요청에 필요한 로직을 처리한다.

  4. 처리 중 JSP의 JSTL 문법을 해체하여 로직을 통해 나온 데이터를 더해 순수한 html코드로 변환하여 response로 내보낸다.

  5. WAS는 나온 response를 HttpServletResponse 객체의 형태로 바꾸어 Web Server로 내보낸다.

  6. 쓰레드를 종료하고, 요청에 관한 HttpServletRequest 객체와 HttpServletResponse 객체를 제거한다.

  7. Web Server는 HttpServletResponse를 클라이언트에 보낸다.

위와 같은 방식으로 JSP를 통해 화면을 구성하는 방법이 일반화되면서 , 웹시장은 Servlet, JSP를 함께 활용하는 현재의 Server Side Rendering 환경이 갖추어지게 된다.

  • Controller는 User로부터 요청을 받고, Model에 명령한다.

  • Model은 Controller로부터 명령을 받아 상태를 수정한다.

  • View는 사용자에게 보여줄 정보를 Model로부터 받아 화면을 구성한다.

이 시점에서 비즈니스 로직을 처리하는 Servlet과 DB를 담당하는 개발자(Model), 퍼블리싱과 JSP를 처리하는 개발자의 역할(View)이 나뉘게 된다.

서블릿의 생성

서블릿은 추상 클래스 HttpServlet 을 extend 해서 만들어진다.

HttpServlet에는 생명주기 관리를 위한 init(), service(), destroy() 메서드가 있고, 각 메서드의 요청을 처리하기 위한 doGet(), doPost(), doPut(), doDelete() 등의 메서드가 있다.

서블릿의 동작과정

  1. 사용자가 URL을 클릭하면 HTTP Request를 서블릿 컨테이너로 전송한다.

  2. Http Request를 전달받은 서블릿 컨테이너는 HttpServletRequest, HttpServletResponse 두 객체를 생성한다.

  3. web.xml 에는 어떤 URL에 어떤 서블릿 컨테이너에 mapping 할지 쓰여있고 이에 따라 서블릿으로 이를 전달해준다. @WebServlet 어노테이션을 이용해서도 매핑을 할 수 있다.

  4. 해당 서블릿에서 service 메서드를 호출하고 클라이언트의 요청 종류(Get,Post..)에 따라 doGet, doPost ... 를 호출한다.

  5. doGet, doPost ... 메서드는 동적으로 페이지를 생성한 후 HttpServletResponse 에 응답을 보낸다.

  6. 응답이 끝나면 HttpServletRequest, HttpServletResponse 두 객체를 소멸시킨다.

멀티쓰레드 지원 및 관리

서블릿 컨테이너에서는 쓰레드를 만들어 서블릿 객체를 호출하도록 한다. 서블릿 컨테이너는 여러 클라이언트가 서버에 요청을 보내게 되면 여러개의 쓰레드를 생성하고 각 쓰레드는 서블릿 객체를 호출하여 작업을 처리한다.

하지만 모든 요청마다 쓰레드를 생성하게 되면 동시 요청은 처리할 수는 있지만 쓰레드 생성 비용과 쓰레드의 컨텍스트 스위칭 비용이 발생할 수 있다. 그리고 너무 많은 요청이 들어오면 쓰레드를 무한정 생성해야 하기 때문에 CPU의 한계를 넘어서서 서버가 다운될 수 있는 상황까지 초래하게 된다.

그래서 WAS는 아래처럼 쓰레드 풀이라는 개념을 사용한다.

쓰레드 풀은 처음에 일정한 수의 쓰레드를 미리 생성해놓고 클라이언트의 요청이 오면 쓰레드 풀 안에 있는 쓰레드를 할당하고 요청을 처리하고 나면 해당 쓰레드를 다시 반납 받는다.

톰캣은 최대 200개의 쓰레드를 쓰레드 풀에 생성한다. 이로 인해 쓰레드 생성과 종료 비용이 절약되고, 응답 시간이 빨라질 수 있다.

쓰레드가 모두 사용 중인 상황에서는 기다리는 요청에 대해 특정 숫자만큼만 대기하도록 설정할 수 있도록 만들수도 있죠.

결국 핵심은 WAS가 멀티 쓰레드 지원을 통한 동시 요청 처리를 해준다는 것이다.

하나의 DispatcherServlet만 두고 모든 요청을 처리한다. 각 HTTP 요청마다 생성되거나 할당되는 스레드는 Request-handling thread이다. 위의 200개 쓰레드

Last updated