모르지 않다는 것은 아는것과 다르다.

Spring

SpringMVC

채마스 2022. 2. 26. 02:20

개요

  • SpringMVC 패턴을 이해하기 위해서 기본적으로 알아야 될 지식들을 정리하고자 한다.

웹 서버(Web Server)

  • HTTP 기반으로 동작한다.

  • 정적 리소스를 제공한다.
  • 정적(파일)에는 HTML, CSS, JS, 이미지, 영상등이 있다.
  • 웹 서버의 예로는 NGINX, APACHE 등이 있다.

 

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

  • HTTP 기반으로 동작한다.
  • 프로그램 코드를 실행해서 애플리케이션 로직을 수행한다.

  • 동적 HTML 를 처리한다.

  • HTTP API(JSON) 등을 핸들링할 수 있다.
  • 서블릿, JSP, 스프링 MVC 가 WAS에서 실행된다.
  • 웹 서버가 하는 기능 대부분을 포함하고있다.
  • 예로는 Tomcat, Undertow, Jetty 등이 있다.

 

 

WAS로만 애플리케이션을 구성하면 안될까?

  • 가능은 하지만 매우 비효율적이다.
  • WAS는 애플리케이션 코드를 실행하는데 특화되어 있다.
  • 만약 WAS만으로 웹 시스템을 구성한다면, WAS가 너무 많은 역할을 담당하게 되고, 이는 서버 과부하로 이어질 수 있다.
  • 또한 중요한 애플리케이션 로직이, 단순한 정적 리소스를 때문에 수행이 어려울 수 있다.
  • WAS 장애시 오류 화면도 노출 불가능하다. (예를들어, "죄송합니다 현재 서버가 부하되어 사용이 어렵습니다"와 같은 화면)
  • 한마디로 WAS를 단순하고 용량이 큰 정적리소스를 사용하기 위해 사용하기에는 아깝다!

 

웹 시스템 구성

  • 정적 리소스는 웹 서버가 처리한다.
  • 웹 서버는 애플리케이션 로직같은 동적인 처리가 필요하면 WAS에게 요청을 위임 한다.
  • 이렇게 되면 웹 서버는 값싸고 단순한 정적리소스를 처리하고, WAS는 중요한 애플리케이션 로직만 전담해서 처리할 수 있다.
  • 정적 리소스만 제공하는 웹서버는 잘 죽지 않는다. 그렇기 때문에 잘 죽는 WAS에서 오류 발생시 오류화면을 사용자에게 띄워줄 수 있다.
  • 정적 리소스가 많아지면 웹서버를 증설하고, 애플리케이션 리소스가 많아지면 WAS를 증설하는 식으로 시스템은 발전할 수 있다.

 

 

서블릿

  • 서블릿이란 - 클라이언트가 어떠한 요청을 하면 그에 대한 결과를 다시 전송해주어야 하는데, 이러한 역할을 하는 자바 프로그램입니다.
  • 이러한 정의로는 서블릿의 기능을 이해하기 어렵다.
  • 그럼 만약 서블릿이 없다면, 개발가는 어떠한 일들을 더해줘야 할까? 아래와 같은 일들을 개발자가 직접해줘야 한다.
    ```
  1. 서버 TCP/IP 대기, 소캣 연결
  2. HTTP 요청 메시지를 파싱해서 읽기
  3. POST 방식, /save URL 인지 확인
  4. Content-Type 확인
  5. HTTP 메시지 바디 내용 파싱
  6. 저장 프로세스 실행
  7. HTTP 응답 메시지 생성 시작 (HTTP 시작라인 생성, Header 생성, 메시지 바디에 HTML 생성해서 입력)
  8. TCP/IP에 응답 전달, 소켓 종료
    ```
  • 보통 의미있는 비즈니스 로직은 6번과 7번 사이에 실행된다.
  • 서블릿을 사용하게 된다면, 개발자는 비즈니스 로직에만 집중할 수 있다.

 

 

서버의 요청응답 구조

  • HTTP 요청시
  1. WAS는 Request, Response 객체를 새로 만들어서 서블릿 객체 호출
  2. 개발자는 Request 객체에서 HTTP 요청 정보를 편리하게 꺼내서 사용
  3. 개발자는 Response 객체에 HTTP 응답 정보를 편리하게 입력
  4. WAS는 Response 객체에 담겨있는 내용으로 HTTP 응답 정보를 생성

 

 

서블릿 컨테이너

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

 

 

쓰레드

  • 백엔드 개발자는 멀티 쓰레드에 대한 개념은 필수이다.

  • client가 요청을한 후 TCP/IP 연결이 된 다음 서블릿은 누가 호출하는가 -> 쓰레드가 호출한다.
  • 애플리케니션 코드를 하나하나 순차적으로 실행하는 것은 쓰레드이다.
  • 쓰레드가 없다면 자바 애플리케이션 실행이 불가능하다.
  • 쓰레드는 한번에 하나의 코드 라인만 수행할 수 있다. (하나하나 순차적으로 내려간다. 건너뛰기는 안된다.)
  • 동시 처리가 필요하면 쓰레드를 추가로 생성해야된다.

  • 단일 쓰레드 환경에서 이미 쓰레드가 사용중이라면, 새로운 요청을 바로 처리할 수 없다.
  • 이렇게 되면 두 연결 모두 정상적으로 작동하지 못하고 죽을 수 있다.

  • 해결하고 싶다면 추가로 쓰레드를 생성하면 된다.
  • 하지만 쓰레드를 새로 생성하는 비용과, 컨텍스트 스위칭 비용이 발생한다.
  • 이러한 문제를 spring은 어떻게 보완해 주고 있는가

 

 

다중 쓰레드

  • Spring은 쓰레드 풀에 일정 개수의 쓰레드를 생성해둔다.
  • 요청을 처리할 때마다 쓰레드를 새로 생성하는 것이 아니라, 쓰레드 풀에서 쓰레드를 가져다가 사용한다.
  • 쓰레드 풀에 생성 가능한 쓰레드의 최대치를 관리한다.
  • 쓰레드의 사용아 종료되면 다시 쓰레드풀에 반납한다.
  • 미리 생성된 쓰레드를 사용하기 때문에 쓰레드를 생성하고, 종료하는 비용이 절약되고, 응답시간이 빠르다.
  • 생성 가능한 쓰레드의 최대치가 있으므로 너무 많은 요청이 들어와도 기존 요청은 안전하게 처리할 수 있다.
  • 멀티 쓰레드에 대한 부분은 WAS가 처리하기 때문에 개발자는 멀티 쓰레드 관련 코드를 신경스지 않아도 된다.
  • 개발자는 싱글 쓰레드 프로그래밍을 하듯이 편리하게 소스를 개발할 수 있다.
  • 하지만 싱글톤 객체(서블릿, 스프링 빈)에서 공유변수를 잘관리해야 된다. (멀티쓰레드기 때문에 어디서 공유된 변수가 바뀔지 모름)

 

 

쓰레드 풀의 적정 숫자

  • 너무 낮게 설정한다면 -> 동시요청이 많아지면, 서버 리소스는 여유롭지만, 클라이언트는 금방 응답이 지연된다.
  • 너무 높게 설정하면 -> 동시요청이 많아지면, CPU, 메모리 리소스 임계점 초과로 서버가 다운된다.
  • 애플리케이션 로직의 복잡도, CPU, 메모리, IO 리소스 상황에 따라 풀에 담길 쓰레드의 수는 달라진다.
  • 성능 테스트 툴로는 아파티 ab, 제이미터, nGrinder등이 있다.

 

 

 

REFERENCES

  • 김영한님의 스프링 MVC 1편

'Spring' 카테고리의 다른 글

빈 생명주기와 콜백  (0) 2022.02.26
Transactional Propagation  (0) 2022.02.26
BindingResult  (0) 2022.02.26
Bean Validation (BindingResult 개념을 먼저 숙지 해야된다.)  (0) 2022.02.26
ApplicationRunner,CommandLineRunner  (0) 2022.02.26