스프링

서블릿(Servlet)

쿠쿠s 2022. 5. 31. 22:26

서블릿(Servlet) 이란?

  • 서블릿이란 동적인 페이지를 만들기 위해 사용되는 웹 애플리케이션 프로그램
  • 낮은 성능 및 낮은 수준의 확장성과 같은  CGI 의 한계를 해결

 

CGI (Common Gateway Interface)는 뭔가요?

  • CGI 는 실제로 C 또는 C++ 와 같은 프로그래밍 언어를 사용하여 작성된 외부 응용 프로그램이며 클라이언트 요청을 처리하고 동적 콘텐츠를 생성하는 역할

CGI 동작 방식

  • CGI 는 이처럼 서버에서 모든 요청에 대한 프로세스를 만들기 때문에 많은 요청이 있을 경우 메모리에 적재하여 CPU할당을 받아 실행되는 프로세스는 서버에 부하가 많이 일어난다.

 

그래서 이를 해결하고자 모든 새 요청에 대해 프로세스를 생성하지 않고, 모든 요청을 동시에 처리하는 단일 인스턴스만 존재하는 서블릿을 사용합니다.

 

 

서블릿 동작방식

CGI에 비해 서블릿에는 많은 장점이 있습니다.

  • 웹 컨테이너는 서블릿에 대한 여러 요청을 처리하기 위한 스레드를 생성합니다.
  • 스레드는 공통 메모리 영역을 공유하고, 가벼우며, 스레드 간의 통신 비용이 낮다는 점에서 프로세스에 비해 많은 이점이 있다

 

 

 

다시 돌아와 서블릿을 지원하는 WAS 를 사용하게 된다면 HTTP 요청과 응답을 직접 하나하나 파싱하여 처리를 하지 않고 의미있는 비즈니스 로직에만 집중하여 개발 할 수 있습니다.

 

  • urlPatterns(/hello) 의  URL이 호출되면 서블릿 코드가 실행됩니다.
  • HTTP 요청 정보를 쉽게 사용할 수 있고,  처리 결과를 쉽게 응답으로 반환 가능하다.
  • 개발자는 HTTP 스펙을 매우 편리하게 사용 할 수 있습니다.

 

 

 

서블릿 컨테이너와 서블릿 동작 방식

  • 서블릿 컨테이너는 톰캣처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 합니다.

 

 

 

HTTP 요청이 들어오면 서블릿은 해당 요청과 매핑된 서블릿을 찾게 됩니다.

WAS는 HTTP 요청 메시지를 기반으로 Request, Response 객체를 새로 만들어서 서블릿 인스턴스가 컨테이너에 있는지 확인을 합니다. 없다면 생성을 하여 컨테이너에 스레드를 생성하고 HelloServelt을(애플리케이션 로직)을 실행하여 WAS는 Response 객체를 바탕으로 HTTP 응답 메세지를 만들어 웹 브라우저에 전달을 하게 됩니다.

 

 

서블릿은 컨테이너는 서블릿 객체 생성, 초기화, 호출, 종료하는 생명주기 관리 합니다.

요청이 올때마다 계속 객체를 생성하는것은 비효율이기 때문에 서블릿 객체는 싱글톤으로 관리합니다. 최초 로딩 시점에 서블릿 객체를 미리 만들어 두고 재활용하며 모든 요청은 동일한 서블릿 객체 인스턴스에 접근하게 됩니다.

 

 

만약 한 요청을 처리하기전에 다른 요청이 들어오면 동시 요청을 처리하기 위해 멀티스레드로 사용합니다.

멀티 스레드는 주의해야할 점이 많습니다. 요청마다 스레드를 생성하게 된다면 리소스가 허용할 때 까지 처리가 가능하지만 쓰레드의 생성 비용은 비싸고, 컨텍스트 스위칭 오버헤드가 발생하게 됩니다. 만약 제한을 두지않는다면 하드웨어의 임계점을 넘으면 서버가 죽을 수 있습니다.

 

그래서 위와 같이 스레드를 미리 만들어 스레드 풀에 보관하고 관리해야 합니다. 스레드가 필요하면 이미 생성되어 있는 스레드를 꺼내서 사용하고 종료하면 다시 스레드 풀에 반납하는 형태입니다.

 

 

다시 돌아와 요청당 서블릿을 생성하게 되면 비효율적인 부분이 있습니다. 멀티스레드의 관리도 어렵고, 공통 로직처리가 어렵습니다. 기능이 복잡해질수록 컨트롤러에서 공통으로 처리해야하는 부분이 점점 더 많아 질 것입니다. 그래서 먼저 공통 기능을 처리하는 프론트 컨트롤러 패턴을 도입하면 해결할 수 있습니다. 모든 요청을 받는 전면 컨트롤러 서블릿을 Dispatcher Servlet 이라고 부릅니다. 

 

 

 

 

스프링 MVC의 프론트 컨트롤러가 바로 디스패처 서블릿(DispatcherServlet)입니다.

 

 

동작순서

  1. 핸들러 조회: 핸들러 매핑을 통해 요청 URL에 매핑된 핸들러(컨트롤러)를 조회한다.
  2. 핸들러 어댑터 조회:  핸들러를 실행할 수 있는 핸들러 어댑터를 조회한다.
  3. 핸들러 어댑터 실행: 핸들러 어댑터를 실행한다.
  4. 핸들러 실행: 핸들러 어댑터가 실제 핸들러를 실행한다.
  5. ModelAndView 반환: 핸들러 어댑터는 핸들러가 반환하는 정보를 ModelAndView로 변환해서 반환한다.
  6. viewResolver 호출: 뷰 리졸버를 찾고 실행한다.
  7. View 반환: 뷰 리졸버는 뷰의 논리 이름을 물리 이름으로 바꾸고, 렌더링 역할을 담당하는 뷰 객체를 반환한다.
  8. 뷰 렌더링:  뷰를 통해서 뷰를 렌더링 한다.

 

 

스프링 MVC의 큰 강점은 디스패처 서블릿 코드의 변경없이, 원하는 기능을 변경하거나 확장할 수 있습니다.

 

구조가 많이 복잡해 보이고 처리해야 할게 많아 보이지만 개발자가 실제로 처리해야하는 부분은 핸들러(컨트롤러)에 집중하면 됩니다. 즉 요청처리 로직들에게만 신경을 쓰면 됩니다. 나머지는 역할은 디스패처서블릿이 스프링 컨테이너로부터 주입을 받아 동작을 하게 됩니다.

 

결론은 개발자가 서블릿을 활용함으로서 복잡한 부분을 처리하지 않고 쉽게 요청,응답 처리를 할 수 있습니다.

 

 

 

 

 

 

 

참고 - 인프런 김영한 강사님

10분 테크톡 코키님

https://www.javatpoint.com/servlet-tutorial

https://www.youtube.com/watch?v=2pBsXI01J6M&ab_channel=우아한Tech

 

'스프링' 카테고리의 다른 글

Builder Pattern (빌더 패턴)  (0) 2022.06.28
XSS 와 CSRF  (0) 2022.06.05
싱글톤 패턴(Singleton)  (0) 2022.05.26
REST ? RESTful ? REST API?  (0) 2022.05.26
관심사의 분리(Seperation Of Concern)  (2) 2022.05.18