220315 Spring MVC
—————————————————— 웹 서버, 웹 애플리케이션 서버
모든 것이 HTTP!!
- 웹 서버(Web Server)  HTTP 기반으로 동작 정적 리소스 제공, 기타 부가 기능
예) NGINX, APACHE
- 웹 애플리케이션 서버(WAS)
HTTP 기반으로 동작
웹 서버 기능 포함 + (정적 리소스 제공 가능) 프로그램 코드를 실행해서 애플리케이션 로직 수행
- 동적 HTML, HTTP API(JSON)
- 서블릿, JSP, 스프링 MVC
예) 톰캣, Jetty, Undertow
- 웹 서버, 웹 애플리케이션 서버 차이
웹 서버는 정적 리소스, WAS는 애플리케이션 로직 사실은…. 둘의 용어도 경계도 모호함..
자바는 서블릿 컨테이너 기능을 제공하면 WAS
- 서블릿 없이 자바코드를 실행하는 서버 프레임워크도 있음
WAS는 애플리케이션 코드를 실행하는데 특화
- 웹 시스템 구성 - WAS, DB WAS, DB만으로 시스템 구성 가능 WAS는 애플리케이션 로직도 모두 제공 가능.  하지만!!! WAS가 너무 많은 역할을 담당, 서버 과부하 우려 가장 비싼 애플리케이션 로직이 정적 리소스 때문에 수행이 어려울 수 있음. WAS 장애시 오류 화면도 노출 불가능..(완전 다운)
 일반적으로는 이렇게 함. 정적 리소스는 웹 서버가 처리 웹 서버는 애플리케이션 로직같은 동적인 처리가 필요하면 WAS에 요청을 위임 WAS는 중요한 애플리케이션 로직 처리를 전담.
그리고** 이렇게 하면 효율적인 리소스 관리가 가능하다.
*** 정적 리소스가 많이 사용되면 Web Server 서버 증설 , 애플리케이션 리소스가 만힝 사용되면 WAS 증설!!
정적 리소스만 제공하는 웹 서버는 잘 죽지 않음 ! (오류화면 HTML을 갖고 있다가 WAS가 죽으면 보여주면 됨 ㅎ) 애플리케이션 로직이 동작하는 WAS 서버는 잘 죽음… WAS, DB 장애시 Web서버가 오류 화면 제공 가능
———————————— 서블릿
 서블릿은 의미있는 비즈니스 로직을 제외하고 서버 TCP/IP대기, 소켓 연결부터 종료까지의 반복적인 작업을 해준다.
 서블릿은 이렇게 작성하면, HTTP 요청 정보, 응답 정보를 편리하게 사용, 개발자는 HTTP 스펙을 매우 편리하게 사용

서블릿 HTTP 요청, 응답 흐름
HTTP 요청 시 : WAS는 Request, Response객체를 새로 만들어서 서블릿 객체 호출 개발자는 Request 객체에서 HTTP 요청 정보를 편리하게 꺼내서 사용 개발자는 Response 객체에 HTTP 응답 정보를 편리하게 입력 WAS는 Response 객체에 담겨있는 내용으로 HTTP 응답 정보를 생성
- 서블릿 컨테이너 톰캣처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 함 서블릿 컨테이너는 서블릿 객체를 생성, 초기화, 호출, 종료하는 생명주기 관리 서블릿 객체는 싱글톤으로 관리
- WAS에 들어오는 request, response는 객체가 새로 생성되나 서블릿 객체는 그럴 필요가 없다.
- 고객의 요청이 올 떄 마다 계속 객체를 생성하는 것은 비효율
- 최초 로딩 시점에 서블릿 객체를 미리 만들어두고 재활용
- 모든 고객 요청은 동일한 서블릿 객체 인스턴스에 접근
- 공유 변수 사용 주의 *************
- 서블릿 컨테이너 종료 시 함께 종료 JSP도 서블릿으로 변환 되어서 사용 ******동시 요청을 위한 멀티 쓰레드 처리 지원
———————- 동시 요청 - 멀티 쓰레드 **** 매우 중요 개념 정리 필수
쓰레드
- 애플리케이션 코드를 하나하나 순차적으로 실행하는 것은 쓰레드
- 자바 메인 메서드를 처음 실행하면 main이라는 이름의 쓰레드가 실행
- 쓰레드가 없다면 자바 애플리케이션 실행이 불가능
- 쓰레드는 한번에 하나의 코드 라인만 수행
- 동시 처리가 필요하면 쓰레드를 추가로 생성
 요청은 두개인데 쓰레드가 하나, 근데 처리가 지연되면 둘 다 동작을 못하게 됨
- 요청 마다 쓰레드 생성 장단점
장점 : 동시 요청을 처리할 수 있음, 리소스(CPU, 메모리)가 허용할 때 까지 처리 가능 하나의 쓰레드가 지연 되어도 나머지 쓰레드는 정상 동작
단점 : 쓰레드는 생성 비용이 매우 비싸다. 많이 만들면 응답 속도가 늦어진다. 쓰레드는 컨텍스트 스위칭 비용이 발생한다. 쓰레드 생성에 제한이 없다.
-
고객 요청이 너무 많으면, CPU, 메모리 임계점을 넘어서 서버가 죽을 수 있다. 위 서버가 죽지 않기 위해 쓰레드 풀을 만듬
-
쓰레드 풀  쓰레드를 풀 안에 만들어 놓고 쓰고 반납한다.
쓰레드 풀이 꽉 차면 쓰레드 대기, or 거절
특징 : 필요한 쓰레드를 쓰레드 풀에서 보관하고 관리 쓰레드 풀에 생성 가능한 쓰레드의 최대치를 관리한다. 톰캣은 최대 200개 기본 설정(변경가능)
사용 : 쓰레드가 필요하면, 이미 생성되어 있는 쓰레드를 쓰레드 풀에서 꺼내어 사용한다. 사용을 종료하면 쓰레드 풀에 해당 쓰레드를 반납한다. 최대 쓰레드가 모두 사용중이면? 특정 숫자만 큼 기다리거나, 거절
장점 : 쓰레드가 미리 생성되어 있으므로, 쓰레드 생성 종료 비용(CPU)이 절약 응답 시간 빠르다. 생성 가능한 쓰레드의 최대치가 있으므로 너무 많은 요청이 들어와도 기존 요청은 안전하게 처리
실무 팁 : WAS의 주요 튜닝 포인트는 최대 쓰레드(max thread)수 이다. 이 값을 너무 낮게 설정하면?
- 동시 요청이 많으면, 서버 리소스는 여유롭지만, 클라이언트는 금방 응답 지연 (예) 너무 낮으면 쓰레드 대기 거절이 나서 확인해 봤더니 CPU 사용률이 5%이면.. 많이 부끄러운 것… 좋은 환경을 갖고도 활용을 제대로 못한 것이다.
이 값을 너무 높게 설정하면?
- 동시 요청이 많으면, 임계점 초과로 서버가 다운되어버림;;;;; 죽으면 또 복구하기 쉽지 안ㅇ흠…
장애 발생 시 ?
- 클라우드면 일단 서버부터 늘리고, 이후에 튜닝
- 클라우드가 아니면 열심히 튜닝……
쓰레드 풀 적정 숫자는? 애플리케이션 로직 복잡도, 여러 상황 다 다름 즉 성능 테스트를 꼭 해봐야 함… 최대한 실제 서비스와 유사하게 성능 테스트를 시도 해봐야 한다.. 툴 : 아파치 ab, 제이미터, nGrinder 등…
핵심은..!! WAS가 멀티 쓰레드를 지원해준다 멀티 쓰레드에 대한 부분을 WAS가 처리 개발자가 멀티 쓰레드 관련 코드를 신경쓰지 않아도 됨 개발자는 마치 싱글 쓰레드 프로그래밍을 하듯이 편리하게 소스 코드를 개발 멀티 쓰레드 환경이므로 싱글톤 객체(섭르릿, 스프링 빈)는 주의해서 사용
—————————————————— HTML, HTTP API, CSR ,SSR
-
정적 리소스 고정된 HTML파일, CSS, JS , 이미지, 영상 제공 주로 웹 브라우저
-
동적 HTML 페이지는 JSP나 타임리프를 사용해서 WAS에서 HTML파일을 생성해서 내려줌
-
HTTP API HTML이 아니라 데이터를 전달 주로 JSON 형식 사용 다양한 시스템에서 호출 HTML파일을 내려주는 것이 아닌 JSON 정보를 내려줌.(주로 JSON) 페이지 렌더링이 아님  UI 클라이언트 접점, 서버 to 서버(MSA)랑 주고 받음
** 이 위에 세개를 백앤드 개발자는 고민을 해야함 ㅎ
-
SSR = 서버 사이드 렌더링 서버에서 최종 HTML을 생성해서 클라이언트에 전달
-
CSR = 클라이언트 사이드 렌더링  HTML 결과를 자바스크립트를 사용해서 웹 브라우저에서 동적으로 생성해서 적용 주로 동작인 화면에 사용, 웹 환경을 마치 앱처럼 필요한 부분부분 변경할 수 있음 예) 구글 지도. Gmail, 구글 캘린더 관련 기술 : React, Vuew.js -> 프론트
참고 : React,Vuejs를 CSR + SSR 동시에 지원하는 웹 프레임워크도 있음 SSR을 사용하더라도, 자바스크립트를 사용해서 화면 일부를 동적으로 변경 가능
 타임리프가 거의 쓰임 스프링에서 밀어줌 그리고 화면이 정적이고 단순해서 하루면 대충 다 알고 2~3일이면 바로 쓸 수 있음 ㅎ 간단한건 뚝딱 만듬, 하나는 알아야 함 필수
백엔드 개발자는 서버, DB, 인프라 등등.. 수 많은 백엔드 기술을 공부해야 한다..
——————————————————— 자바 웹 기술 역사
과거 기술
서블릿 - 1997 : HTML생성이 어려움
JSP - 1999 : HTML생성은 편리하지만, 비즈니스 로직까지 너무 많은 역할을 담당
서블릿, JSP을 조합해서 MVC 패턴 사용 : 모델, 뷰, 컨트롤러로 역할을 나누어 개발
MVC 프레임워크 춘추 전국 시대 - 2000년 초 ~ 2010년 초 : MVC 패턴 자동화, 복잡한 웹 기술을 편리하게 사용할 수 있는 다양한 기능 지원 스트럿츠, 웹워크, 스프링 MVC(과거 버전)
결국…
애노테이션 기반의 스프링 MVC 등장 @Controller MVC 프레임워크의 춘추 전국 시대 마무리 ㅎㅎ…
스프링 부트의 등장 : 스프링 부트는 서버를 내장 과거에는 서버에 WAS를 직접 설치하고, 소스는 War파일을 만들어서 설치한 WAS에 배포 스프링 부트는 빌드 결과(Jar)에 WAS 서버 포함 -> 빌드 배포 단순화
최신 기술 - 스프링 웹 기술의 분화
Web Servlet - Spring MVC Web Reactive - Spring WebFlux
최신 기술 - 스프링 웹 플럭스 : 특징 : 비동기 넌 블러킹 처리 최소 쓰레드로 최대 성능 - 쓰레드 컨텍스트 스위칭 비용 효율화 함수형 스타일로 개발 - 동시처리 코드 효율화 서블릿 기술 사용 x
그런데 : 웹 플럭스는 기술적 난이도 매우 높음 아직은 RDB 지원 부족 일반 MVC의 쓰레드 모델도 충분히 빠름 실무에서 아직 많이 사용하지 않음(전체 1% 이하)
자바 뷰 템플릿 역사 : HTML을 편리하게 생성하는 뷰 기능
JSP : 속도 느림, 기능 부족
프리마커, 벨로시티 : 속도 문제 해결, 다양한 기능 타임 리프 : 내추럴 템플릿 : HTML의 모양을 유지하면서 뷰 템플릿 적용 가능 스프링 MVC와 강력한 기능 통합 (스프링에서 밀어주는 기술)
최선의 선택, 단! 성능은 프리마커, 벨로시티가 더 빠름.. ㅎ
서블릿 —————————— JSP 프로젝트 생성
보통은 Jar를 쓰는데 War 선택 JSP 써야해서..
—————————— Hello 서블릿
원래는 스프링 없이도 가능하지만 톰캣 깔고 할려면 번거로움;  서블릿을 사용해서 request로 들어오는 객체의 값을 편하게 사용할 수 있고, 반대로 response에서 전달할 값들을 편하게 보낼 수 있다.
@WebServlet : 서블릿 애노테이션 name : 서블릿 이름 urlPatterns: URL 매핑
 웹 브라우저가 요청이 오면 request,response 객체를 만들어 줌 그 객체를 이제 서블릿 컨테이너에 서블릿 객체로 만들고 이것은 싱글톤 객체로 만들고 request,response를 넘겨줌 그리고 서블릿 객체가 종료되고 나가면서 response를 만들어서 웹 브라우저로 넘겨줌
HTTP 응답에서 Content-Length는 WAS가 알아서 만들어 줌
—————————————— HttpServletRequest -개요
역할 : HTTP 요청 메시지를 개발자가 직접 파싱해서 사용해도 되지만. 매우 불편. 서블릿은 개발자 HTTP 요청 메시지를 편리하게 사용할 수 있도록 기능 제공. 그리고 그 결과를 “HttpServletRequest”객체에 담아서 제공
- START LINE HTTP 메소드 URL 쿼리 스트링 스키마, 프로토콜
- 헤더 헤더 조회
- 바디 form 파라미터 형식 조회 message body 데이터 직접 조회
HttpServletRequest 객체는 추가로 여러가지 부가기능도 함께 제공한다.

*** 중요 : HttpServletRequest, HttpServletResponse를 사용할 때 가장 중요한 점은 이 객체들이 HTTP 요청 메시지, HTTP 응답 메시지를 편리하게 사용하도록 도와주는 객체라는 점!! 따라서 이 기능에 대해서 깊이 있는 이해를 하려면 “HTTP 스펙이 제공하는 요청, 응답 메시지를 이해해야 함”
————————————— HttpRequestServlet 사용법
 이렇게 getXXX로 request의 여러 정보를 알 수 있다.
지금까진 Header, startline을 알아봄
———————————————————— HTTP 요청 데이터 - 개요
HTTP 요청 메시지를 통해 클라이언트에서 서버로 데이터를 전달하는 방법
주로 3가지 방법을 쓴다.
-
GET - 쿼리 파라미터 /url/?username=hello&age=20 메시지 바디 없이, URL의 쿼리 파라미터에 데이터를 포함해서 전달 예) 검색, 필터, 페이징 등에서 많이 사용
-
POST - HTML Form *** content-type : application/x-www-form-urlencoded 메시지 바디에 쿼리 파라미터 형식으로 전달,!! username=hello&age=20 예 ) 회원 가입, 상품 주문, HTML Form 사용
-
HTTP message body에 데이터를 직접 담아서 요청 **** HTTP API에서 주로 사용, JSON, XML, TEXT 데이터 형식은 주로 JSON을 사용 POST, PUT, PATCH 다 사용 가능