[Spring] 스프링 MVC 1편 1.웹 어플리케이션 이해
(1) 웹서버, 웹 어플리케이션 서버
1. HTTP 메시지에 모든 것을 전송
http를 기반으로 모든 형태의 데이터 전송이 가능
-html, text
-이미지,음성,영상,파일
-json, xml(api)
2.웹서버, 웹 어플리케이션 서버
웹서버 - http를 기반으로 동작하는 서버, 정적 리소스 제공
웹 어플리케이션 서버 [WAS]
- http를 기반, 프로그램 코드를 실행해 어플리케이션 로직 수행
- 동적 html 생성 , http api(json) 제공 가능
- servlet, jsp, spring mvc 가 WAS에서 동작
차이점
-경계 모호함
-WAS 는 어플리케이션 코드 실행에 더 특화된 서버 정도
3.웹 시스템 구성
WAS + DB 만으로 구성 가능
WAS는 정적 리소스, 어플리케이션 로직 모두 제공 가능하므로
BUT// WAS의 서버 과부화 우려 *WAS는 장애시 오류 화면 노출도 불가능
=>> 보통 WEB server + WAS + DB로 구성
정적리소스는 웹 서버에서 *오류화면 출력 가능
어플리케이션 로직만 WAS에서 담당
API만 제공하는 API 서버를 구축할 경우 웹서버 없이 WAS만으로 구성해도 됨
(2) 서블릿
0. html form 데이터 전송
웹브라우저가 post 방식의 http 요청 메시지를 만들어 서버로 전송
1.서버에서 처리해야 하는 업무
WAS를 직접 구현시
-서버에 TCP/IP 연결 대기 후, 연결이 들어오면 소켓을 연결하도록 함
-HTTP 요청 메시지는 단순 텍스트 -> parsing을 통해 post 방식과 save URL 인식
-Content-type을 확인하고, 이에 따라 메시지 바디의 내용도 parsing
-저장에 대한 비즈니스 로직 실행, 데베에 저장 요청 **의미있는 비즈니스 로직
-저장 결과를 웹 브라우저에 전달하기 위해 HTTP 응답 메시지를 직접 생성
-TCP/IP로 HTTP 응답 메시지를 전달하고 소켓을 종료함
=의미있는 로직 수행 전 후 로 단계가 너무 많아 비효율적
=> 서블릿을 지원하는 WAS 사용
-서블릿은 의미있는 비즈니스 로직을 제외한 모든 작업을 지원해, 서블릿을 지원하는 WAS에서는 TCP/IP 연결, HTTP 요청 메시지 파싱, HTTP 응답 메시지 생성까지 자동화됨
2.서블릿
코드 *HttpServlet 상속
@WebServlet(name="helloServlet",urlPatterns="/hello")
public class HelloServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest request,HttpServletResponse response){
//어플리케이션 로직
}
}
-urlPatterns(/hello)의 URL이 호출되면 해당 서블릿 코드가 실행됨
-HTTP 요청/응답 정보를 편리하게 사용할 수 있는 HttpServletRequest, HttpServletResponse 사용
HttpServiceRequest : 객체에 파싱된 HTTP 요청 메시지의 내용이 들어있음
HttpServletResponse : 객체에 원하는 데이터를 넣으면 HTTP 응답 메시지를 생성할 수 있음
HTTP 요청 시 응답 흐름
3.서블릿 컨테이너
톰캣처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 함
서블릿 컨테이너는 서블릿 객체를 생성, 초기화, 호출, 종료하는 생명 주기 관리
-작성한 서블릿 객체를 개발자가 생성할 필요 x
고객의 요청이 올 때마다 계속 객체 생성x (비효율) => 싱글톤으로 관리
- Request, Response 객체는 클라이언트 요청시 마다 생성하는 것이 맞음
-하지만 어플리케이션 로직을 작동시키는 서블릿 객체는 재사용함
-최초 로딩 시점에 서블릿 객체를 미리 생성 후 서블릿 컨테이너 종료시 함께 종료
-모든 고객 요청은 동일한 서블릿 객체 인스턴스에 접근하므로, 공유 변수 사용에 주의
JSP도 서블릿으로 변환되어 사용
동시 요청을 위한 멀티스레드 처리 지원
(3) 동시 요청 - 멀티 스레드
1. 스레드
클라이언트에서 서버로 요청 메시지를 보내면 WAS가 응답
이때, TCP/IP connection이 연결되고, WAS가 서블릿 호출
이 서블릿을 호출하는 게 스레드
어플리케이션 코드를 하나하나 순차적으로 실행하는 것이 스레드
- 스레드는 한번에 하나의 코드 라인만
- 스레드가 없다면 자바 어플리케이션 실행 불가능
자바 메인 메소드를 처음 실행하면 main 스레드가 실행됨
동시 처리가 필요하면 스레드를 추가로 생성함
1.1 스레드 하나 사용
WAS 내에 스레드가 한 개 있다고 가정
1.1.1 단일 요청
클라이언트로부터 요청이 하나 오면, 하나 있는 스레드가 할당되어 서블릿 코드를 실행함
응답을 수행 한 후에는 다시 휴식 상태로
1.1.2 다중요청
스레드는 하나인데 여러개의 요청이 들어오는 경우, 차례대로 스레드 할당 되어 서블릿 코드 실행
1번 요청 처리가 잘 되면, 순차적으로 2번 요청에 대한 응답 수행
but, 1번 요청을 처리하는 과정에 서블릿 코드 내부의 이유로 인한 지연이 발생
이 지연 발생 중 2번 요청이 들어온다면, 스레드가 하나뿐이므로 대기
지연이 길어지면 1번,2번 연결 모두 죽어버려 2번 요청에 대한 수행 자체가 불가함
=>
1.2 요청마다 스레드 생성
다중 요청시 스레드를 하나 더 생성하고 동일한 서블릿을 호출해 2번 요청을 처리
이처럼 요청이 오면 스레드를 생성하고, 요청이 끝나면 스레드를 종료하는 식으로 WAS를 구현해도 됨
1.2.1 장점
- 동시 요청 처리 가능
- 리소스 (cpu, memory)가 허용될 때까지 요청 처리 가능
- 하나의 스레드가 지연되더라도, 나머지 스레드는 정상 동작 가능
1.2.2 단점
- 스레드 생성에 cpu 많이 사용됨 -> 고객의 요청이 올 때마다 스레드를 생성하면 응답속도 느려짐
- cpu core에서 각 스레드를 전환시 context switching 비용 발생 *스레드가 많아질수록 높은 비용
- 스레드 생성에 제한이 없으며, cpu/memory 임계점이 넘으면 서버 죽을 수도
=>
2. 스레드 풀
1.2의 단점을 보완하는 방법으로 대부분의 WAS 구현 방식
2.1 특징
- 필요한 스레드를 스레드 풀에 보관하고 관리
- 스레드 풀에 생성 가능한 스레드의 최대치를 관리함
*스프링 부트에서 사용하는 톰캣 - 기본 설정 200개 (변경가능)
2.2 사용
- 스레드가 필요할 때마다 스레드 풀에 요청해, 이미 생성되어 잇는 스레드를 받아 사용
- 스레드 사용을 종료하면 반납 *스레드를 종료하는 것 xx
- 최대 스레드가 모두 사용중이어서 스레드 풀에 스레드가 없는 경우 요청을 거절 or 대기하도록 설정
2.3 장점
- 스레드가 미리 생성되어 있으므로, 스레드를 생성하고 종료하는 비용이 절약되어 응답 시간이 빠름
- 생성 가능한 스레드의 최대치가 정해져있으므로, 많은 요청이 들어와도 스레드 풀이 감당할 수 있는 만큼만 안전하게 처리 가능
2.4 tip
- WAS의 주요 튜닝 포인트 : 최대 스레드 수
- 낮게 설정 -> 서버 리소스는 여유/ 클라이언트는 잦은 응답 지연 = 비효율
- 높게 설정 -> cpu/memory 리소스 임계점 초과로 서버 다운
- 장애 발생시,
클라우드 환경 - 일단 서버부터 늘려서 서비스는 살리고 튜닝
클라우드 환경 x - 튜닝
**적절한 최대 스레드 수 찾기
*실제 서비스와 유사한 성능테스트 시도해야함
3. WAS의 멀티 스레드 지원
멀티스레드에 대한 부분은 WAS가 처리해 개발자가 신경 xx
(싱글 스레드 프로그래밍하듯 개발하면 됨
멀티 스레드 환경이므로, 싱글톤 객체(서블릿, 스프링 빈) 주의해서 사용
(4) HTML, HTTP API, CSR, SSR
1. 정적 리소스, HTML 페이지, HTTP API
*백엔드 개발자가 서비스를 제공할 때 고민해야되는 포인트 세가지
1.1 정적 리소스
정적 리소스 제공시, 고정된 HTML 파일, css, js image,video 등 제공
- 요청이 들어오면 웹 서버가 이미 생성되어있는 리소스를 조회해 반환함
1.2 HTML 페이지
동적으로 필요한 HTML 파일을 생성해서 전달하는 방식
-요청이 들어오면, 어플리케이션 로직을 수행할 수 있는 WAS가 데이터베이스를 조회
- 조회한 데이터를 바탕으로 동적으로 HTML을 생성해 클라이언트에 전달
* HTML 생성에 JSP, 타임리프 등 뷰 템플릿 사용
웹브라우저는 HTML 해석 (렌더링)
1.3 HTTP API
HTML이 아니라 주로 JSON 형식을 사용해 데이터를 전달하는 방식
-요청이 들어오면, 어플리케이션 로직을 수행할 수 있는 WAS가 데이터 베이스를 조회
- 조회한 데이터를 바탕으로 JSON 형식의 데이터를 생성해 클라이언트에 전달
데이터만 주고 받으며 UI 화면 필요시, 클라이언트가 별도 처리
앱, 웹 클라이언트, 서버 2 서버 등 다양한 시스템에서 호출
앱 클라이언트- 데이터를 받아 앱의 UI 컴포넌트를 이용해 사용자에게 뷰 제공
웹 클라이언트- 데이터를 받아 React, Vue.js 같은 웹 클라이언트를 이용해 사용자에게 뷰 제공
서버 2 서버 - HTML 필요 없이 데이터만 주고 받으면 됨
*기업 간 데이터 통신 시 *요즘 한 기업 안에서도 여러 서비스들이 쪼개져 있고, 각 서버는 HTTP API로 통신
2. SSR, CSR
2.1 SSR 서버 사이드 렌더링
서버에서 HTML 최종 결과를 만들어 클라이언트에 전달하는 방식
- 주로 정적인 화면에서 사용
- 관련 기술 : JSP, thymeleaf
- ssr을 사용하더라도, js를 사용해 화면 일부를 동적 변경 가능
- 요청이 들어오면, 어플리케이션 로직을 수행 할 수 있는 WAS가 데이터베이스 조회
- 조회한 데이터를 바탕으로 동적으로 HTML을 생성해 클라이언트에 전달
*서버에서 JSP,thymeleaf 같은 뷰템플릿 사용해서 HTML 생성
2.2 CSR 클라이언트 사이드 렌더링
클라이언트에서 js를 사용해 HTML 결과를 동적으로 생성해 적용하는 방식
-관련 기술 : React, Vue.js
- React, Vue.js를 csr + ssr 동시 지원하는 웹 프레임워크도 존재
주로 동적인 화면에 사용해 앱처럼 필요한 부분부분 변경 가능
ex) google map, gmail
1. 웹 브라우저가 서버에 HTML을 요청하면, 서버는 응답으로 어플리케이션을 구동하는 js 링크를 제외하면 텅 빈 HTML 정송
<!-- Html -->
<html>
<head>
...
</head>
<body>
<div id="root"></div>
<script src="app.js"></script>
</body>
</html>
2. 응답을 받은 웹 브라우저는 js를 요청하고, 서버는 클라이언트 로직과 HTML 렌더링 코드가 담긴 js코드를 전송
3. 웹 브라우저는 HTTP API를 이용해 서버를 호출하고, 서버는 데이터베이스를 조회해 얻은 값을 JSON형식으로 전송
4. 웹 브라우저는 클라이언트 로직, HTML 렌더링 코드, HTTP API를 통해 전송받은 데이터를 이용해 동적으로 렌더링
(5) 자바 백엔드 웹 기술 역사
1. 자바 웹 기술 역사
1.1 과거 기술
- 서블릿 : 자바 코드를 사용해 HTML을 동적으로 생성하기 어려움
- JSP : HTML 생성은 편리하나, 비즈니스 로직까지 너무 많은 역할을 부여 *코드가 수천줄이 넘어가며 유지/보수가 어려워짐
- 서블릿 + JSP 의 MVC 패턴 : 모델, 뷰, 컨트롤러로 역할을 나누어 개발
-> MVC 프레임 워크 시대
- MVC 패턴 자동화, 복잡한 웹 기술을 편리하게 사용할 수 있는 다양한 기능 지원
- 스트럿츠, 웹위크, 스프링 MVC
1.2 현재 사용하는 기술
- 어노테이션 기반의 스프링 MVC가 등장
- 서버가 내장된 스프링 부트의 등장
* 스프링 부트는 스프링을 사용하며 불편한점들을 자동화
* 빌드 결과(jar)에 WAS 서버가 포함되어 있어, 빌드/배포의 단순화가 이루어짐
1.3 최신 기술
-Web Servlet - Spring MVC
* 스프링 MVC는 기본적으로 서블릿을 기반으로 동작
* 동시 처리를 위한 멀티 스레드 지원
* 현재 실무에서 대부분 사용
- Web Reactive - Spring WebFlux
* 비동기 논블로킹 처리
* 최소 스레드로 최대 성능을 발휘해, 스레드 컨텍스트 스위칭 비용 최소화
* 함수형 스타일 -> 동시 처리 코드를 효율화
* 서블릿 기술을 사용하지 않음
** 웹 플럭스의 기술적 난이도 매우 높으나 일반 MVC 스레드 모델도 충분히 빠름
** 웹 플럭스의 관계형 데이터베이스 지원은 아직 부족 -> 아직 많이 사용 x
2. 자바 뷰 템플릿 역사
- 뷰 템플릿은 HTML을 편리하게 생성하는 View 기능
- JSP : 속도 느리고 기능 부족
- 프리마커(Freemarker), 벨로시티(Velocity) : 속도 문제 해결, 다양한 기능
- 타임리프(Thymeleaf) * 최선
: 내추럴 템플릿 - HTML 모양을 유지하면서 뷰 템플릿 적용 가능
: 스프링 MVC와 강력한 통합 기능
: 단, 성능 자체는 프리마커, 벨로시티 보다 느림