Spring

서블릿(Servlet) 기본

dev-rootable 2023. 7. 11. 19:12

📌 서블릿이란

 

일반적으로 클라이언트-서버 구조에서 HTTP 상에서 요청과 응답이 일어나려면 필요한 작업이 많다.

 

ex) TCP/IP 연결, HTTP 요청 메시지 생성, 비즈니스 로직 처리, HTTP 응답 메시지 생성, TCP/IP 연결 종료 등등

 

이러한 작업들을 개발자가 구현하면 매번 반복적인 작업을 구현하는데 많은 시간을 소모하게 된다. 그래서 비즈니스 로직 처리 외 HTTP 요청 및 응답과 관련된 작업들을 처리하는 역할이 필요하게 되었는데, 이를 수행하기 위해 서블릿이 등장했다.

 

클라이언트 요청을 처리하고 그에 대한 응답을 주기 위한 자바 프로그램

 

🔎 특징

 

  • 웹 서버가 동적인 페이지를 제공할 수 있도록 도와주는 애플리케이션
  • 클라이언트 요청에 대해 동적으로 작동
  • HTML을 사용하여 응답
  • Java Thread를 이용하여 동작
  • Spring MVC 패턴에서 Controller로 이용됨
  • HTTP 프로토콜 서비스를 지원하는 javax.servlet.http.HttpServlet 클래스를 상속받음
  • UDP보다 처리 속도가 느림
  • HTML 변경 시 Servlet을 재컴파일해야 하는 단점

 

📌 기본 코드

 

기본 코드

 

HttpServlet을 상속받아 사용해야 하며, @WebServlet을 통해 서블릿의 이름을 지정하고 어떤 요청 URL 패턴에 응답할지 지정할 수 있다.

 

✔ HttpServletRequest

 

HTTP 요청 정보를 편리하게 사용하도록 HTTP 요청 메시지 값을 파싱 해서 가져올 수 있음

 

클라이언트가 서버로 보내는 요청 정보를 처리하는 객체

 

✔ HttpServletResponse

 

HTTP 응답 정보를 편리하게 제공

 

서버가 클라이언트로 보내는 응답 정보를 처리하는 객체

 

📌 동작 방식

 

출처: https://mangkyu.tistory.com/14

 

1. 클라이언트가 URL을 입력하면 HTTP Request가 요청을 서블릿 컨테이너로 전송

2. 요청을 전송 받은 서블릿 컨테이너는 HttpServletRequest, HttpServletResponse 객체를 생성

3. web.xml을 기반으로 사용자가 요청한 URL이 어느 서블릿에 대한 요청인지 탐색

4. 해당 서블릿에서 service()를 호출한 후 클라이언트의 Get, Post 여부에 따라 doGet(), doPost() 호출

5. doGet() 또는 doPost() 메서드는 동적 페이지를 생성한 후 HttpServletResponse 객체에 응답을 보냄

6. 응답이 끝나면 HttpServletRequest, HttpServletResponse 두 객체는 소멸

 

🔎 서블릿 컨테이너(Servlet Container)란

 

  • Tomcat처럼 서블릿을 지원하는 WAS서블릿 컨테이너라고 함
  • 개발자가 작성한 서블릿 객체를 생성, 초기화, 호출, 종료하는 생명주기를 관리
  • 서블릿 객체는 싱글톤으로 관리
  • JSP도 서블릿으로 변환되어서 사용
  • 동시 요청을 위한 멀티 쓰레드 처리 지원

 

✔ 서블릿을 싱글톤으로 관리하는 이유

 

서블릿 컨테이너는 최초 로딩 시점에 서블릿 객체를 미리 만들어두고 재활용하는 싱글톤 방식을 사용한다. 이렇게 생성한 자원을 재활용하면 동일한 URL을 처리하는 요청에 대해 매번 서블릿을 새로 생성하지 않아도 되므로 서블릿 자원을 효율적으로 관리할 수 있다. 단, 동일한 URL에 동시 요청이 온다면 멀티 쓰레드를 통한 처리가 필요하다.

 

📌 동시 요청 처리 - Multi Thread

 

🔎 Thread란

 

어떤 프로그램(프로세스) 내에서 애플리케이션 코드를 하나하나 순차적으로 실행해 주는 실행 흐름의 단위

 

Reference:

https://ko.wikipedia.org/wiki/%EC%8A%A4%EB%A0%88%EB%93%9C_(%EC%BB%B4%ED%93%A8%ED%8C%85) 

 

스레드 (컴퓨팅) - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 두 개의 스레드를 실행하고 있는 하나의 프로세스. 스레드(thread)는 어떠한 프로그램 내에서, 특히 프로세스 내에서 실행되는 흐름의 단위를 말한다. 일반적으

ko.wikipedia.org

 

 

🔎 처리 방법 1 - 단일 Thread

 

  • 요청이 오면 Thread를 할당
  • Thread는 서블릿이 지정한 메서드인 service() 코드를 코드 라인마다 수행
  • 서블릿에서 응답 객체를 생성하여 WAS가 응답
  • 응답 후 Thread는 휴식 상태로 돌아감

 

✔ 한계

 

한 Thread가 요청을 처리 중일 때, 또 다른 요청이 온다면 처리 지연 또는 응답 실패가 발생함

 

🔎 처리 방법 2 - 다중 Thread

 

요청마다 Thread를 할당하도록 처리하는 방법

 

✔ 장점

 

  • 동시 요청을 처리할 수 있다.
  • 리소스(CPU, 메모리)가 허용할 때까지 처리 가능
  • 지연에 상관없이 정상 서비스할 수 있다.

 

✔ 단점

 

  • Thread 생성 비용은 매우 비싸고 Context Switching 비용이 발생하여 가격 효율은 떨어진다.
  • 고객 요청마다 Thread를 생성하면 응답 속도가 느려진다.
  • Thread 생성에 제한이 없어 고객 요청이 너무 많으면 CPU나 메모리 임계점을 넘어 서버가 죽을 수 있다.

 

🔎 처리 방법 3 - 쓰레드 풀(Thread Pool)

 

풀에 일정 Thread를 생성해 놓고 할당과 반납을 반복하는 처리 방법

 

생성 가능한 Thread의 최대치를 관리한다.

 

만약 모든 Thread가 사용 중이라면 대기 중인 요청은 거절하거나 특정 숫자만큼만 대기하도록 설정할 수 있다.

 

✔ 동작 과정

 

1. 풀 안에 미리 Thread를 만들어 둠

2. 요청이 오면 유휴 상태의 Thread를 할당하여 처리

3. 사용이 끝나면 쓰레드 풀에 반납

 

✔ 장점

 

  • Thread가 미리 생성되어 있으므로, 생성/종료 비용을 절약하고 응답 시간을 줄일 수 있다.
  • 생성 가능한 Thread의 최대치가 있으므로 많은 요청이 들어와도 기존 요청을 안전하게 처리할 수 있다.

 

✔ 적절한 최대 쓰레드 수

 

쓰레드의 최대치가 너무 낮으면

 

서버 리소스는 여유롭지만 클라이언트는 금방 응답 지연이 발생할 수 있다.

 

쓰레드의  최대치가 너무 높으면

 

동시 요청이 많으면 CPU나 메모리 리소스 임계점 초과로 서버가 다운될 수 있다.

 

결론적으로, 애플리케이션 로직의 복잡도, CPU, 메모리, I/O 리소스 상황에 따라 결정해야 하고 최대한 실제 서비스와 유사하게 성능 테스트를 시도해야 한다.

 

✔ 서블릿 동작 과정 - 쓰레드 풀 사용

 

쓰레드 풀

 

  • WAS가 클라이언트로부터 HTTP 요청을 받아 서블릿 컨테이너로 넘김
  • 컨테이너는 요청 URL을 분석하여 매핑된 서블릿을 메모리에 올림
  • 컨테이너는 Thread Pool에서 유휴 상태 Thread를 하나 꺼냄
  • 서블릿은 해당 쓰레드에게 수행할 메서드를 지정 및 할당
  • Thread는 메서드 수행 후 리턴할 때 함께 종료되고 Thread Pool에 반납됨

 

References:

https://mangkyu.tistory.com/14

 

[JSP] 서블릿(Servlet)이란?

1. Servlet(서블릿) 서블릿을 한 줄로 정의하자면 아래와 같습니다. 클라이언트의 요청을 처리하고, 그 결과를 반환하는 Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍 기술 간단히 말해서,

mangkyu.tistory.com

 

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard

 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., 원

www.inflearn.com