Spring MVC
- Spring MVC는 **Spring Framework의 웹 계층(Web Layer)**을 담당하는 모듈 중 하나로,
Model-View-Controller패턴을 기반으로 한 웹 애플리케이션 개발 프레임워크이다.
MVC
- 기존의 model1 방식(JSP 혹은 Servlet 하나가 모델, 뷰, 컨트롤러 역할을 전부 담당하는 구조)에서 발전한 model2 방식으로 모델, 뷰, 컨트롤러를 각각 분리
- 역할 분리로 유지보수성, 확장성, 테스트 용이성 향상 및 비즈니스 로직 재사용 가능
- View 교체 용이 (HTML, JSON 등)
- Spring MVC는 Model 2 패턴을 프레임워크 레벨에서 자동화, 표준화한 것으로, 중복되는 패턴을 제거해 개발 효율을 높임
Servlet
- 서블릿(Servlet)은 자바(Java)로 웹 요청과 응답을 처리하는 방법에 대한 기술 '명세(Specification)'이자 '인터페이스(Interface)'
- 클라이언트 요청 수신: 웹 브라우저가 /login, /home 같은 URL로 요청을 보내면 서블릿 컨테이너(예: Tomcat)가 요청을 받아 해당 서블릿 클래스의 메서드를 호출합니다.
- 요청 분석: HttpServletRequest 객체를 통해 파라미터, 헤더, 쿠키, 세션 등 클라이언트의 요청 정보를 읽을 수 있습니다.
- 비즈니스 로직 실행: DB 조회나 서비스 호출 등 비즈니스 처리를 수행합니다.
- 응답 생성: HttpServletResponse 객체를 사용해 HTML, JSON, 파일 등으로 응답을 작성해 클라이언트에 전송합니다
Servlet Container
- 톰캣처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 함
- 서블릿 컨테이너는 서블릿 객체를 생성, 초기화, 호출, 종료하는 생명주기 관리
- 서블릿 객체는 싱글톤으로 관리
- 고객의 요청이 올 때 마다 계속 객체를 생성하는 것은 비효율적이므로 최초 로딩 시점에 서블릿 객체를 미리 만들어두고 재활용
- 모든 고객 요청은 동일한 서블릿 객체 인스턴스에 접근
- 공유 변수 사용 주의
- 서블릿 컨테이너 종료시 함께 종료
- JSP도 서블릿으로 변환 되어서 사용
서블릿 컨테이너의 실행과정
- 실행 명령을 받으면 서블릿 컨테이너가 먼저 실행된다.
- 서블릿 컨테이너 내부 앱을 로드 및 실행 하고, Servlet class를 찾아(@WebServlet 어노테이션을 모두 스캔) url를 매핑한다.
- 첫 요청을 받으면 찾아 서블릿 객체를 생성하고, 처리한다.
- 그 후로는 해당 객체 재활용
동시 요청은?
- 애플리케이션 코드를 하나하나 순차적으로 실행하는 것은 쓰레드
- 자바 메인 메서드를 처음 실행하면 main이라는 이름의 쓰레드가 실행
- 요청 마다 쓰레드 생성 -> 쓰레드 생성 비용 때문에 쓰레드 풀이라는 방식을 사용
쓰레드 풀
-
필요한 쓰레드를 쓰레드 풀에 보관하고 관리한다.
-
쓰레드 풀에 생성 가능한 쓰레드의 최대치를 관리한다. 톰캣은 최대 200개 기본 설정 (변경 가능)
-
쓰레드가 필요하면, 이미 생성되어 있는 쓰레드를 쓰레드 풀에서 꺼내서 사용한다.
-
사용을 종료하면 쓰레드 풀에 해당 쓰레드를 반납한다.
-
최대 쓰레드가 모두 사용중이어서 쓰레드 풀에 쓰레드가 없으면 기다리는 요청은 거절하거나 특정 숫자만큼만 대기하도록 설정할 수 있다.
-
장점
- 쓰레드가 미리 생성되어 있으므로, 쓰레드를 생성하고 종료하는 비용(CPU)이 절약되고, 응답 시간이 빠르다.
- 생성 가능한 쓰레드의 최대치가 있으므로 너무 많은 요청이 들어와도 기존 요청은 안전하게 처리할 수 있다.
- WAS의 주요 튜닝 포인트는 최대 쓰레드(max thread)수이다.
- 이 값을 너무 낮게 설정하면?
- 동시 요청이 많으면, 서버 리소스는 여유롭지만, 클라이언트는 금방 응답 지연
- 요청이 많은 상황에서 최소한 CPU 50% 이상은 사용하게 설정해야 한다.
- 이 값을 너무 높게 설정하면?
- 동시 요청이 많으면, CPU, 메모리 리소스 임계점 초과로 서버 다운
- 장애 발생시?
- 클라우드면 일단 서버부터 늘리고, 이후에 튜닝
- 클라우드가 아니면 열심히 튜닝
- 적정 숫자는 어떻게 찾나요?
- 애플리케 이션 로직의 복잡도, CPU, 메모리, IO 리소스 상황에 따라 모두 다름
- 성능 테스트
- 최대한 실제 서비스와 유사하게 성능 테스트 시도
- 툴: 아파치 ab, 제이미터, nGrinder
-
WAS의 멀티 쓰레드 지원
-
멀티 쓰레드에 대한 부분은 WAS가 처리
-
개발자가 멀티 쓰레드 관련 코드를 신경쓰지 않아도 됨
-
개발자는 마치 싱글 쓰레드 프로그래밍을 하듯이 편리하게 소스 코드를 개발
-
멀티 쓰레드 환경이므로 싱글톤 객체(서블릿, 스프링 빈)는 주의해서 사용
Front Controller 패턴
- 프론트 컨트롤러 서블릿 하나로 클라이언트의 요청을 받음
- 프론트 컨트롤러가 요청에 맞는 컨트롤러를 찾아서 호출
- 프론트 컨트롤러를 제외한 나머지 컨트롤러는 서블릿을 사용하지 않아도 됨
- 입구를 하나로 해서 공통 처리 가능
- 스프링 웹 MVC의 DispatcherServlet이 FrontController 패턴으로 구현되어 있음
- 스프링도 용빼는 재주가 있는게 아니라 서블릿이 앞단에 있는 것