0+ 스프링/0+ 스프링 MVC

[스프링 MVC] Java에서 서블릿이 등장한 이유(Feat. 서블릿 기초 개념)

힘들면힘을내는쿼카 2023. 3. 28. 01:08
728x90
반응형

[스프링 MVC] Java에서 서블릿이 등장한 이유(Feat. 서블릿 기초 개념)

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의
이 포스팅은 위 강의를 참고하여 작성하였습니다.

 

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

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

www.inflearn.com

 

 

 

서블릿에 대해서 공부하기 전에 먼저 WAS에 대한 개념이 있어야 합니다.
그래서 먼저 WAS에 대해서 간단하게 소개하겠습니다.🤵🏻

 

 

우리는 하루에도 수십, 수백번 인터넷 🌐 에 접속합니다.
인터넷에 접속하여 원하는 정보를 얻거나 정보를 제공합니다.

어떻게 우리가 이런 작업을 할 수 있을까요? 🤔

 

HTTP

컴퓨터를 통해서 정보를 주고 받기 위해서는 프로토콜이 필요합니다.
프로토콜은 쉽게 생각하면 우리가 사용하는 언어라고 생각하면 쉽습니다.

컴퓨터는 사람의 언어를 이해하지 못합니다.
그래서 사람이 컴퓨터에 맞는 언어를 제공하고, 컴퓨터는 다시 사람이 이해할 수 있는 언어를 제공합니다.

우리가 하루에도 수백, 수천번 접속하는 인터넷에서 주로 사용하는 프로토콜은 HTTP 입니다.

HTTP를 이용해서 모든 것을 전송합니다.

  • HTML, TEXT
  • IMAGE, 음성, 영상, 파일
  • JSON, XML (API)
  • 거의 모든 형태의 데이터 전송 가능!!

 

HTTP를 이용해서 정보를 주고 받는것은 이해했습니다.

그렇다면 정보는 도대체 어디서 제공하고, 저장하는 걸까요? 🤔

 

웹 서버(Web Server)

인터넷에 접속하는 순간, 우리는 웹 서버에 접속했다는 것을 의미합니다.
이 웹 서버는 HTTP 기반으로 동작하게 됩니다.

우리가 브라우저에 www.naver.com을 치고 Enter를 누르는 순간 웹 서버에 접속합니다.

현재, 대부분 웹 서비스는 사용자에 따라서 동적으로 웹 서비스를 제공합니다.
맞춤형 서비스를 제공한다는 의미이죠.^^

하지만, 초기에 웹 서버는 이렇게 맞춤형 서비스를 제공하지 못했습니다.
정적 페이지만을 제공했습니다.
마치 우리가 📕책을 사면, 그 책은 변하지 않습니다.
그 책을 산 누구에게나 같은 페이지를 제공합니다.

이를 그림으로 이야기하면 다음과 같습니다.

 

참고
웹 서버의 특징

  • HTTP 기반으로 동작
  • 정적 리소스 제공
  • 정적(파일) HTML, CSS, JS, 이미지, 영상
  • 예) NGINX, APACHE

 

이런것에 😠 불만을 느낀 개발자들은 동적으로 동작하는 웹 서비스를 갈망 했습니다.

 

웹 애플리케이션 서버(WAS: Web Application Server)

동적으로 동작하는 웹 서버!?
지금 우리가 사용하는 대부분 서비스는 이 WAS로 동작하게 됩니다.

WAS를 사용하면 개발자가 작성한 로직에의해서 동적으로 변하게 만들 수 있게 됩니다.
즉, 개발자가 작성한 로직에 의해서 HTTP 응답이 변합니다.!!

그렇다면 현재 웹 서버는 사용 안하는거야?
아닙니다. 🙅
현재도 웹 서버는 사용하고 있습니다.^^

사실 둘의 용어는 경계가 모호하게 사용되고 있습니다.
웹 서버도 프로그램을 실행하는 기능을 포함하기도 하고, WAS도 웹 서버의 기능을 제공하기 때문입니다.

 

WAS애플리케이션 코드를 실행하는데 더 특화 되어있다고 생각하시면 됩니다. 👍

 

참고
WAS의 특징

  • HTTP 기반으로 동작
  • 웹 서버 기능 포함
    • 정적 리소스 제공 가능
  • 프로그램 코드를 실행해서 애플리케이션 로직 수행
    • 동적 HTML, HTTP API
    • 서블릿, JSP, 스프링 MVC
  • 예) 톰캣 Jetty, Undertow

 

웹 시스템 = 웹 서버 + 웹 애플리케이션 서버

아까 WAS는 웹 서버의 기능도 제공한다고 했습니다.^^
그래서 웹 서비스를 만들기 위해서
WAS, DB 만으로 시스템 구성이 가능합니다.

하지만 점점 사용자가 많아지고, 서비스의 규모가 커지다보면 WAS가 너무 많은 역할을 담당하게 됩니다.
가장 비싼(중요한) 애플리케이션 로직이 정적 리소스 때문에 수행이 어려울 수 있습니다….!!

 

WAS가 장애가 발생하면 오류 화면도 노출이 불가합니다.

 

그래서 정적 리소스는 웹 서버가 처리하고
중요한 애플리케이션 로직은 WAS에게 위임 합니다.

이렇게 구성하면 효율적으로 리소스를 관리할 수 있습니다.
정적 리소스가 많이 사용되면 웹 서버를 증설하고
애플리케이션 리소스가 많이 사용되면 WAS를 증설 합니다.^^

 

또한, 정적 리소스만 제공하는 웹 서버는 오류가 잘 발생하지 않습니다.(잘 안죽어요.)
애플리케이션 로직이 동작하는 WAS는 상대적으로 잘 죽습니다. 😭
WAS, DB로만 웹 시스템을 구성하면 WAS가 죽었을 시에 오류화면도 제공 못했는데
웹 서버, WAS, DB 로 웹 시스템을 구성하면 WAS, DB 장애시 웹 서버가 오류 화면도 제공할 수 있습니다.^^👍

 

HTML Form 데이터 전송

그렇다면 이 포스팅의 주제인 서블릿은 언제 이야기 하는 걸까요? 😡

WAS를 통해 애플리케이션 로직을 작성할 수 있다고 했습니다.
서블릿 존재 이전의 HTML Form 데이터 전송 과정을 살펴 볼까요?

 

이렇게 메시지를 보낸다고 했을 때
서버에서 처리해야 하는 작업을 파악해 봅시다.


음… 서버에서 처리해야 할 작업이 너무 많습니다.
가장 중요한것은 비지니스 로직을 개발하는 일 인데,,,, 모든 작업을 하는것이 과연 의미가 있을까요? 😇

 

서블릿

그래서 등장한 것이 바로 서블릿 입니다.!!

 

서블릿을 사용하면 개발자는 HTTP 스펙을 매우 편리하게 사용할 수 있습니다.

@WebServlet(name = "helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
    @Override 
    protected void service(HttpServletRequest request, HttpServletResponse response) { 
        //비지니스 로직 
    } 
} 
  • urlPatterns(“/hello”)URL이 호출되면 서블릿 코드가 실행
  • HTTP 요청 정보를 편리하게 사용할 수 있는 HttpServletRequest
  • HTTP 응답 정보를 편리하게 사용할 수 있는 HttpServletResponse

 

서블릿 HTTP 요청, 응답 흐름

서블릿에서 HTTP 요청, 응답 흐름은 다음과 같습니다.

  • HTTP 요청
    • WASRequest, Response 객체를 새로 만들어서 서블릿 객체를 호출
    • 🧑‍💻개발자는 Request 객체에서 HTTP 요청 정보를 꺼내서 사용
    • 🧑‍💻개발자는 Response 객체에서 HTTP 응답 정보를 편리하게 입력
    • WASResponse 객체에 담겨있는 내용으로 HTTP 응답 정보를 생성

 

그림으로 표현하면 다음과 같습니다.

서블릿을 지원하는 WAS(톰캣)를 서블릿 컨테이너라고 부릅니다.
서블릿 컨테이너(톰캣)는 서블릿 객체를 생성, 초기화, 호출하는 생명주기를 관리하게 되는데,
서블릿 객체를 모두 싱글톤으로 관리합니다.

 

왜 싱글톤으로 관리할까요? 🤔
그 이유는 요청이 생길 때 마다 서블릿 객체를 계속 생성하는 것은 비효율적이기 때문입니다.
따라서 최초 로딩 시점에 서블릿 객체를 미리 만들어두고 재활용 합니다.
(싱글톤 이기 때문에 공유 변수 사용에 주의!!!!!!!!!!!! 해야 합니다.)
그리고 서블릿 컨테이너 종료시 함께 종료 됩니다.^^

 

어? 그러면 동시 요청이 발생하면 어떻게 하는거지? 🤔
이러한 문제를 해결하기 위해서 멀티 스레드를 지원합니다.!!

 

서블릿 컨테이너에 발생한 동시 요청과 해결 방법(Feat. 멀티 스레드)

잠깐만…!
서블릿이 개발자는 HTTP 스펙을 매우 편리하게 사용할 수 있게 해주는것은 알겠어!

 

그런데 서블릿은 누가 호출하는거야? 🤔
바로 스레드가 호출합니다!!!
애플리케이션 코드를 하나 하나 순차적으로 실행하는 녀석은 스레드 입니다.
Java 메인 메서드를 처음 실행하면 main이라는 이름의 스레드가 시작됩니다.^^
(스레드가 없다면,,, Java 애플리케이션 실행이 불가능 합니다.)

 

그런데, 스레드는 한번에 하나의 코드 라인만 수행합니다.
동시 처리가 필요하면 스레드를 추가로 생성해야 합니다.

 

아래 그림은 스레드 1개를 사용했을 때 다중 요청 상황 입니다.

 

첫 번째 요청에서 처리 지연이 발생하면…. 결국 2개의 요청을 처리 못합니다. 😭

 

하지만, 요청 마다 스레드를 생성하면?!

 

요청 마다 스레드를 생성하면 장단점이 존재합니다.

  • 장점
    • 동시 요청 수행 가능
    • 리소스(메모리, CPU)가 허용할 때 까지 처리 가능
      • 그런데… 이것은 재앙..🤯
    • 하나의 스레드가 지연 되어도, 나머지 스레드는 정상 동작!

 

  • 단점
    • 스레드는 생성 비용이 매우 비싸다… 💸
      • 고객의 요청이 있을 때 마다 스레드를 생성하면, 응답 속도가 늦어짐
    • 스레드는 컨텍스트 스위칭 💸 비용이 발생
      • CPU 코어에서 스레드에서 다른 스레드로 바뀌는 것을 의미합니다.
        • CPU 코어에서 실행되는 단위는 스레드 입니다.
        • 프로세스에 속한 스레드끼리 스위칭이 발생하면 이때는 프로세스 컨텍스트 스위칭이라고 부릅니다.^^
    • 스레드 생성에 제한이 없음
      • 고객 요청이 너무 많으면, 리소스(CPU, 메모리)가 임계점을 넘어 서버가 🤯사망할 수도 있다…

 

이러한 단점을 해결하고자 등장한 것이 바로 스레드 풀 입니다.ㅎㅎ

 

스레드 풀 🏊‍♀️

스레드 풀은 요청 마다 스레드 생성의 단점을 보완하기 위해서 등장했습니다.

어떻게 보완했을까요?
스레드 풀에 필요한 스레드를 미리 생성하고 관리합니다.
스레드 풀에 스레드를 무한개 만큼 미리 만들면 안되기 때문에, 생성 가능한 스레드의 최대치를 관리할 수 있습니다.^^

 


동작과정은 다음과 같습니다.

  • 스레드가 필요하면, 이미 생성되어 있는 스레드를 스레드 풀에서 꺼내서 사용
    • 톰캣은 최대 200개 기본 설정
  • 사용을 종료하면 스레드 풀에 사용한 스레드를 반납
  • 최대 스레드가 모두 사용중이라서 스레드 풀에 스레드가 없으면? 😲
    • 기다리는 요청은 거절하거나, 특정 요청 갯수는 대기열을 만들어 대기하도록 설정할 수 있습니다.^^

스레드 풀을 사용해서 얻는 장점은 정확히 무엇일까요? 🤔

  • 스레드가 미리 생성되어 있기 때문에, 스레드를 생성하고 종료하는 비용(CPU)이 절약되고, 응답 시간이 빠릅니다. 🏃‍♀️
  • 생성 가능한 스레드의 최대치가 있기 때문에, 너무 많은 요청이 들어와도 기존 요청은 안전하게 처리할 수 있습니다.^^

 

참고
WAS의 주요 튜닝 포인트는 최대 스레드 입니다.
이 값을 너무 낮게 설정하면?
동시 요청이 많으면 서버 리소스는 여유 롭지만, 클라이언트는 금방 응답 지연 됩니다…

반대로 이 값을 너무 높게 설정하면?
동시 요청이 많으면, 리소스 임계점에 도달하여 서버가 사망합니다…

적정 숫자는 어떻게…..? 🥲
애플리케이션에 따라 상황이 다르기 때문에, 성능 테스트를 통해 찾아야 합니다!
최대 실제 서비스와 유사하게 성능 테스트를 시도합니다.^^
(저는 아직 해본 적 없습니다….^^)
성능 테스트 툴: 아파치 ab, Jmeter, nGrinder

 

정리

  • 컴퓨터(기계) 끼리 메시지를 주고받기 위해서는 프로토콜이 필요한데 현재 웹 서비스는 HTTP를 다수 이용
  • 웹 서버는 정적 리소스만 제공, 이에 불만을 느낀 개발자들의 요구로 동적 리소스도 제공하는 WAS 등장!
  • WAS는 정적, 동적 리소스를 둘 다 제공할수 있다.
    • 하지만, WAS는 동적 리소스를 제공하는데 더욱 집중하기 웹 시스템 = 웹 서버 + WAS 로 구성
  • WAS로 동적 리소스를 제공할 수 있는데, TCP/IP 통신 부터 메시지 파싱 까지…. 해야할 작업이 너무 많고, 반복적이다.
    이에 불만을 느낀 😡 개발자들에게 WAS는 서블릿을 제공하기 시작함!
  • 👩‍💻개발자는 비지니스 로직에만 집중할 수 있도록 WAS(톰캣)에서 서블릿을 지원
  • 톰캣처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 함
  • 서블릿 컨테이너는 서블릿 객체를 생성, 초기화, 호출, 종료하는 생명주기를 관리
  • 서블릿 객체는 싱글톤으로 관리
    • 싱글톤으로 사용하는 이유
      • 요청이 생길 때 마다 서블릿 객체를 계속 생성하는 것은 비효율적
      • 최초 로딩 시점에 서블릿 객체를 미리 만들어두고 재활용(싱글톤)
      • 모든 요청이 동일한 서블릿 객체 인스턴스에 접근(싱글톤이기 때문)
      • 따라서 공유 변수 사용에 주의!!!! 해야 함
      • 서블릿 컨테이너 종료시 함께 종료
    • 싱글톤을 사용하면 동시 요청은 어떻게 해결하는거지?! 🤔
      • 동시 요청을 위한 멀티 스레드를 지원
  • JSP도 서블릿으로 변환 되어 사용
  • 동시 요청을 위한 멀티 스레드 방식에서 스레드를 생성하고 소멸하는 비용 문제가 발생하여 스레드 풀 지원
    • 스레드는 기본적으로 CPU 코어에서 실행!
  • 스레드 풀은 스레드를 필요한 만큼 미리 생성하고 관리
    • 생성 가능한 스레드 최대치가 존재함(톰캣은 기본 최대 200개)
  • 스레드 풀에 스레드가 미리 생성되어 있기 때문에, 스레드를 생성하고 종료하는 비용 절약 + 응답 시간 개선 👍
  • WAS는 멀티 스레드에 대한 부분을 처리해 줍니다.
    • 이 말은 개발자가 멀티 스레드 관련 코드를 신경 쓰지 않아도 된다는 의미!!
    • 개발자는 싱글 스레드 프로그래밍을 하듯이 편리하게 소스 코드 개발!!!
    • 다만, 싱글톤 객체(서블리, 스프링 빈)는 주의해서 사용해야 합니다.^^

 

 

 

728x90
반응형