[Spring] Spring MVC - Servlet, Servlet Container, Spring Container 에 대해

최동근·2023년 2월 16일
0

스프링

목록 보기
6/8

안녕하세요 오늘은 Spring boot 사용시 필수적으로 알아야 하는 ServletServlet Container 에 대해 알아보겠습니다 👨‍💻

🔔 WAS(Web Application Server) 란?

Servlet 에 대한 전반적인 개념을 배우기 전 WAS(Web Application Server 에 대해 알아봅시다 👀
우리가 사용하는 웹 페이지에는 정적 페이지와 동적 페이지가 존재합니다.

  • 정적 페이지(Static Pages)
    Web Server 는 파일 경로 이름을 받아 경로와 일치하는 file 을 반환합니다.
    이때 항상 동일한 페이지를 반환합니다.
    ex) image, html, css, javascript 과 같이 서버 컴퓨터에 이미 저장되어 있는 파일들

  • 동적 페이지(Dynamic Pages)
    때로는 사용자의 요청에 맞게 동적인 content 을 반환해야합니다.
    즉, Web Server에 의해 실행되는 프로그램을 통해서 만들어진 결과물이 필요합니다.
    이때 동적인 페이지를 생성하기 위해 실행되는 Java Program 을 Servlet 이라고 합니다.
    또한 이러한 프로그램이 실행되는 서버를 WAS 라고 합니다.
    개발자는 Servlet 에 doGet() 구현하게 됩니다.

✅ Web Server 와 WAS 의 차이

  • Web Server 의 기능 🧑🏼‍💻
  • HTTP 프로토콜을 기반으로 하여 클라이언트의 요청을 서비스 하는 기능을 담당
  • 기능1)
    • 정적인 컨텐츠 제공
    • WAS 를 거치지 않고 바로 정적 자원을 제공
  • 기능2)
    • 동적인 컨텐츠 제공을 위한 요청 전달
    • 클라이언트의 요청을 WAS 로 보내고, WAS 가 처리한 결과를 클라이언트에게 전달
  • Web Server 예시
    • Apache Server, Nginx, IIS 등

  • WAS 의 기능 👨‍💻
  • DB 조회나 다양한 로직 처리를 요구하는 동적인 컨텐츠를 제공하기 위해 만들어진 Application Server
  • HTTP 를 통해 컴퓨터나 장치에 어플리케이션을 수행해주는 미들웨어
  • 웹 컨테이너 혹은 서블릿 컨테이너라고 불림
  • WAS = Web Server + Web Container
  • 기능)
    • 프로그램 실행 환경과 DB 접속 기능 제공
    • 여러 개의 트랜잭션 관리 기능
    • 업무를 처리하는 비즈니스 로직 수행
  • WAS 예시
    • Tomcat, JBoss 등

✅ Web Server 와 WAS 를 구분하는 이유

앞에서도 언급했던 것처럼 웹 페이지는 정적 컨텐츠와 동적 컨텐츠가 모두 존재합니다.
따라서 사용자의 요청에 따라 이미 만들어진 웹 페이지를 응답으로 보낼 때와 동적으로 웹 페이지를 생성하여 보내는 경우가 존재합니다.

만약 Web Server 만 이용한다면 클라이언트가 원하는 요청에 대한 결과값을 모두 미리 만들어 놓고 서비스를 해야합니다. 하지만 이는 자원의 효율성 측면에서 매우 안좋습니다.
따라서 WAS 를 통해 요청에 맞는 데이터를 DB 에서 가져와서 비즈니스 로직에 맞게 동적으로 결과를 만들어서 제공함으로써 자원을 효율적으로 사용할 수 있습니다.

또한, WAS 도 Web Server 의 기능을 할 수 있지만 Web Server 을 따로 두는 이유는
서로의 역할을 분담함으로써 서버의 부담을 줄이기 위함입니다

✅ Web Service Architecture

1. 클라이언트가 HTTP 프로토콜을 사용해서 요청을 Web Server 에게 보냅니다.
2. Web Server 는 클라이언트로부터 HTTP 요청을 받습니다.
3. 클라이언트의 요청이 정적 페이지인 경우 Web Server 는 파일 경로 이름을 통해 file content 를 바로 반환합니다.
4. 클라이언트의 요청이 동적 페이지인 경우 Web Server 는 클라이언트의 요청을 WAS로 보냅니다.
5. WAS 는 관련된 Servlet 을 힙 메모리에 올립니다.
6. WAS 는 web.xml 을 참조하여 해당 Servlet 에 대한 Thread 를 생성합니다.
7. Servlet 의 Service() 메소드를 호출합니다. 이때 요청에 맞게 doGet() or doPost() 를 호출합니다.
8. 인자에 맞게 생성된 적절한 동적 페이지를 Response 객체에 담아 WAS 에 전달합니다.
9. WAS 는 Response 객체를 HttpResponse 형태로 바꾸어 Web Server 에 전달합니다.
10. 생성된 Thread 를 종료하고 관련된 객체를 모두 제거합니다.


🔔 Servlet 이란?

서블릿(Servlet) 은 클라이언트의 요청을 처리하고, 그 결과를 다시 클라이언트에게 전송하는 Servlet 클래스의 구현 규칙을 지킨 자바 프로그램입니다.
Servlet 을 통해 웹 페이지를 동적으로 생성하여 클라이언트에게 반환해 줄 수 있습니다 👨‍💻
만약 Servlet 이 없다면 요청과 응답을 일일이 처리해야합니다.
이는 개발자 입장에서는 굉장히 버겁고 복잡한 일입니다. 하지만 Servlet 을 통해 개발자는 비즈니스 로직에만 집중하여 게발을 진행할 수 있습니다 💪

✅ Servlet의 생명 주기

  • 클라이언트 요청이 들어오면 Servlet ContainerServlet 이 힙 영역에 있는지 확인합니다.
    만약 존재하지 않는다면 init() 메소드를 호출하여 적재합니다.
  • 클라이언트 요청에 따라서 service() 메소드를 통해 요청에 대한 응답이 생성됩니다.
  • Servlet ContainerServlet 종료 요청을 하면 destory() 메소드가 호출됩니다.
    종료시 처리해야 하는 작업은 destory() 메소드를 오버라이딩하여 구현하면 됩니다. 종료된 Servlet 인스턴스는 CG 에 의해 메모리에서 제거됩니다.
// 서블릿 예시
@WebServlet(name = "HelloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
	@Override
    protected void service(HttpServletRequest request, HttpServletResponse response) { 
    	// 애플리케이션 로직
	}
}

해당 코드는 개발자가 커스텀하는 HelloServlet 을 나타내는 코드입니다.
urlPatterns에 맞는 URL 이 호출되면 해당 서블릿 코드가 실행됩니다.
이를 통해 개발자는 HTTP 스펙을 매우 편리하게 사용하여 원하는 로직 구현을 할 수 있습니다 ❗️

✅ 싱글톤 패턴의 Servlet

Servlet 인스턴스는 싱글톤으로 생성되며, Thread-Safe 하지 않기 때문에 무상태 혹은 읽기 전용 상태, 동기화 처리된 구조로 설계되어야 합니다.
이러한 특성을 가지는 ServletServlet Container 가 멀티 쓰레딩 기능을 통해 관리합니다.
해당 내용은 밑에서 구체적으로 공부해보겠습니다 🧐


🔔 Servlet Container

Servlet 은 스스로 작동하지 않으며, 서블릿을 관리해주는 것이 필요합니다.
이러한 역할을 Servlet Container 가 합니다.
Servlet Container(Web Container) 는 구현되어 있는 Servlet 클래스의 규칙에 맞게 Servlet 객체를 생성, 초기화, 호출, 종료하는 생명 주기를 관리하는 컨테이너입니다.
클라이언트의 요청을 받고 응답할 수 있도록 웹 서버와 소켓으로 통신하며 우리가 알고 있는 Tomcat 은 대표적인 웹 어플리케이션(WAS) 중 하나로, Servlet Container 기능을 제공합니다.

✅ Servlet Container의 기능

  • 웹 서버와 통신 지원

    Servlet ContainerServletWeb Server 가 통신할 수 있도록 해줍니다.
    이를 Servlet Container 가 알아서 해주기 때문에 개발자는 통신 기능에 대해서 신경 쓰지 않고
    클라이언트의 요청에 대한 비즈니스 로직에만 집중할 수 있습니다 💪

  • Servlet 생명주기 관리

    Servlet 의 생성과 호출 소멸을 관리합니다.
    요청이 들어오면 관련된 Servlet 을 찾고 없다면 초기화합니다.
    또한 Servlet 의 service() 메소드를 호출해서 실제 기능을 하도록 합니다.
    Servlet 의 역할이 끝난후 GC 를 진행하여 관련된 인스턴스를 소멸시킵니다.

  • 멀티 쓰레딩 관리

    앞에서 언급했던 것처럼 Servlet Container 가 관리하는 Servlet 은 싱글톤 패턴으로 관리됩니다. 그렇다면 동시에 같은 Servlet 로 여러 요청이 들어올 때 어떻게 처리할 수 있을까요?
    Servlet Container 는 요청이 들어올 때마다 새로운 자바 쓰레드를 생성하여 멀티 쓰레딩 방식으로 처리합니다.
    여기서 쓰레드는 무한적으로 생성할 수 있는것은 아닙니다.
    Servlet Container 내부에는 쓰레드 풀을 가지고 있으며 기본 값으로 200개의 쓰레드(톰캣 기준)가 존재합니다.

    요청이 들어오면 쓰레드 풀에서 쓰레드를 하나 가져옵니다 ❗️(컨트롤러는 Thread-Safe 함)

  • JSP 지원
    JSP(Java Server Page) 를 Servlet 으로 변환시켜 처리합니다.

해당 이미지는 Servlet Container 를 도식화한 이미지입니다.
해당 이미지를 통해 앞에서 언급했던 것처럼 멀티 쓰레딩을 통해 Servlet 을 처리하는 것을 확인할 수 있습니다 ❗️

✅ Servlet Container 정리

  • 톰캣처럼 서블릿을 지원하는 WAS을 Servlet Container 라고 함
  • Servlet Container 는 Servlet 객체를 생성, 초기화, 호출 ,종료 하는 생명주기 관리
  • Servlet 객체는 싱글톤으로 관리
    클라이언트가 보내는 정보만 다를뿐 형식은 동일하기 때문
    즉, 요청 마다 Servlet 객체를 계속 생성하는 것은 비효율적이기에 최초 로딩 시점에 Servlet 객체를 미리 만들어두고 재활용
    모든 클라이언트의 요청은 동일한 Servlet 객체 인스턴스에 접근
    Servlet Container 종료시 함께 종료
  • 동시 요청을 위한 멀티 쓰레드 처리 지원

🔔 Spring Container

마지막으로 앞에서 배운 내용을 Spring Container 와 연관시켜 정리해보겠습니다.
Spring 을 배울 때 Spring Container 에 동작 원리에 대해 배우는 것은 필수적인 단계입니다.

스프링 컨테이너는 Bean 생명 주기를 관리합니다 👨‍💻
Bean을 관리하기 위해 IoC가 이용되며 BeanFactory 객체가 바로 IoC 컨테이너(=DI 컨테이너, 스프링 컨테이너)에 해당되며, 이 IoC 컨테이너를 상속하면서 부가 기능을 추가한 것이 ApplicationContext입니다.

Spring MVC 역시 서블릿 컨테이너가 관리하고 있는 거대한 서블릿이라고 생각하면 됩니다. 그래서 서블릿 없이 Spring MVC만 있으면 된다고 하는 것은 비즈니스 로직을 Spring을 통해 처리한다는 것이지, 서블릿이 필요 없다는 뜻이 아닙니다.

아래 그림을 보면, 스프링 컨테이너는 서블릿 컨테이너 안에 존재하는 것을 확인할 수 있습니다. 즉, 스프링 컨테이너는 서블릿 컨테이너와 독립적인 존재가 아니며, 서블릿 컨테이너가 Spring Bean에 접근하려면 스프링 컨테이너를 거쳐야 합니다.


참고

[Spring] Servlet, Servlet Container, Spring MVC 정리
[Spring] Dispatcher-Servlet(디스패처 서블릿)이란? 디스패처 서블릿의 개념과 동작 과정
Web Server와 Web Application Server
[Web] Web Server와 WAS 차이와 웹 서비스 구조
Web Server와 WAS의 차이

profile
비즈니스가치를추구하는개발자

0개의 댓글