김영한 강사님의 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술을 듣고 정리한 내용입니다. 자세한 내용은 강의를 참고해주세요
- 우리는 http 통신을 이용해 클라이언트와 서버간의 통신을 한다
- 우리가 url을 주소창에 치면, 인터넷을 통해서 서버에 접근한다
- 서버에서 html을 만들어서 클라이언트에게 내려준다
- 웹 브라우저가 받은 html을 랜더링해서 화면에 보여준다
- http 안에 html,text,json,xml등등 여러 형태의 데이터를 전송한다.
- 또한 서버간의 데이터를 주고 받을 때도, http프로토컬을 이용한다.
웹 서버와 웹 애플리케이션 서버(WAS)
1. 웹 서버
- HTTP 기반으로 동작
- 정적 리소스 제공, 기타 부가기능
- 정적(파일), HTML, CSS, JS, 이미지, 영상등을 서버에서 html로 전환해서 화면에 랜더링을 해준다
2. 웹 애플리케이션 서버(WAS)
- HTTP 기반으로 동작
- 웹 서버 기능 포함 + (정적 리소스 제공 가능)
- 프로그램 코드를 실행해서 애플리케이션 로직 수행
- 동적 HTML, HTTP API(JSON)
- 서블릿, JSP, 스프링 MVC
- 톰켓,Jetty, Undertow
3. 웹 서버, 웹 애플리케이션 서버(WAS)의 차이
- 웹 서버는 정적 리소스(파일), WAS는 애플리케이션 로직 까지
- 둘의 용어의 경계 모호
- 웹 서버도 프로그램을 실행시키는 기능도 포함되어 있기도 함
- 웹 애플리케이션 서버도 웹 서버의 기능을 제공함
- 그래서 그냥 자바에서는 서블릿 컨테이너 기능을 제공하면 WAS 라고 한다
WAS는 애플리케이션 코드를 실행하는데 특화되어 있다
웹 시스템 구성
- WAS, DB
최소한의 단위이다.
WAS가 너무 많은 역할을 담당해서 서버 과부화의 우려가 있다
WAS가 정적 리소스, 동적 리소스 모두 담당한다
가장 비싼 애플리케이션 로직이 정적 리소스 땜에 수행이 어려우면 안된다...
그래서 정적 리소스를 담당하는 Web Server을 앞에 둔다
- WEB, WAS, DB
정적 리소스(HTML,CSS,JS)같은 것들은 웹 서버가 처리
웹 서버는 애플리케이션 로직같은 동적인 처리가 필요하면 WAS에게 위임
WAS는 중요한 애플리케이션 로직만 실행
역할을 나누었다! -> SRP
웹 페이지에 정적 리소스가 많아지면 Web Server증진, 동적 리소스가 많아지면 WAS 증설

- 서버는 보통 개발 로직인 WAS부분에서 많이 오류가 난다.
- WAS, DB만 있으면 오류가 나도 오류 화면 노출이 불가능하다.
- 하지만 Web Server와 WAS를 분리하면, 호류 화면 노출이 해결이 가능하다
- Web Server에서 WAS에 동적인 로직을 위임했지만, WAS나 DB가 오류가 났다면...
- Web Server는 응답(커넥션)을 받지 못했고, 이런 경우 Web Server에서 미리 준비된 오류 화면 HTML을 클라이언트에게 띄어준다

서블릿
- 우리가 http메시지를 받는다고 가정을 해보자
- http 메시지 또한 String 텍스트이다. 그래서 parsing을 이용해서 어떤 형식으로 받고, 어떤 head고, 어떤 내용인지 하나하나 분석을 해야한다... -> 너무 귀찮고, - 개발자는 귀찮은 것을 싫어함
- 그래서 서블릿을 이용해 요청받은 http메시지를 객체로 바꿔 편리하게 내용 정보를 읽는다.
- 그래서 우리는 서블릿을 지원하는 WAS를 사용한다
@WebServlet의 파라미터 urlPattern의 url이 호출되어서 http 메시지가 전달되면, 서블릿 코드의 메서드 service가 실행된다.
- 기본적인 http 스펙은 알고 있어야 한다...

- 이렇게 HTTP 메시지를 받고 TCP/IP연결하고 HTTP 요청 메시지를 파싱한다
- 하나하나 확인하고... 비지니스 로직 실행(여기선 POST니까 Body내용을 DB에 저장한다)
- 그리고 응답 메시지를 만들어서 전송하고,,, 소켓을 종료한다
- 그치만 개발자들은 귀찮은게 싫으니까 Servlet을 사용하고!!!

- 저 초록색 네모 부분 즉 비지니스 로직부분만 실행 한다!!!
- Servlet이 나 나머지 부분을 제외하고 다 지원해준다!!!

- urlPattern이 실행되면 서블릿 코드가 실행된다
- 요청,응답 정보를 편리하게 사용하기 위해서 객체를 만들어준다
- 개발자는 HTTP 스펙을 매우 편리하게 사용할 수 있다.

다시 그림을 보고 과정을 써본다면..
1. HTTP 요청이 오면(urlPatterns를 보고 찾는다) 웹 어플리케이션 서버 WAS는 Request, Response 객체를 새로 만든다
2. @WebServlet으로 서블릿 컨테이너에 등록된 helloServlet에 파라미터로 만들어진 request, response 객체가 들어가서 Service 메서드가 실행된다
3. WAS는 Response객체에 담겨있는 내용을 토대로 HTTP 응답 정보를 생성한다
4. 이때 개발자는 request,response 객체를 이용해 HTTP 요청,응답 정보를 쉽게 사용할 수 있다
서블릿 컨테이너 : 톰켓처럼 서블릿을 지원하는 WAS(웹 어플리케이션)을 말한다.
- 단순히 파싱이유 말고도 여러 이유 때문에 서블릿 컨테이너를 쓴다
싱글톤 서블릿 객체와, 멀티 쓰레드를 지원하는 이유!!!(물론 파싱도 대신해준다)
- 서블릿 컨테이너는 서블릿 객체를 생성, 초기화, 호출, 종료 하는 생명 주기를 관리한다
- 서블릿 객체는
싱글톤으로 관리된다
- 고객의 요청이 올 때 마다 계속 서블릿 객체를 생성하는 것은 비효율적
- 최초 로딩 시점에 서블릿 객체를 만들어서 재활용
- 모든 고객 요청은 동일한 서블릿 객체 인스턴스에 접근한다
- 하지만, 고객의 요청과 응답은 모두 다르기 때문에
Request, Response 객체는 모두 다르다
- 붕어빵의 맛은 손님마다 다 다르지만, 붕어빵 기계는 하나여도 된다!!!
- 싱글톤 객체는 항상말하지만 공유변수 사용을 주의해야 한다(Stateless 상태로 유지되어야 한다)
- 싱글톤 객체의 필드(맴버 변수)의 값을 변경하면 매우 큰일이 일어난다!!!
- 잘못하면 내가 로그인한 정보를 다른 사람이 볼 수 있다
- 서블릿 컨테이너 종료시 서블릿 객체 또한 함께 종료
- JSP 또한 서블릿으로 변환되어서 사용한다
- 서블릿은 동시 요청을 위한
멀티 쓰레드 처리를 지원한다.
멀티쓰레드
프로세스: 프로그램을 실행하는 것
쓰레드 : 프로그램 안에서 애플리케이션 코드를 실행하는 것
- 애플리케이션 코드를 하나하나 순차적으로 실행하는 것 :
쓰레드
- 쓰레드가 없다면, 자바 애플리케이션 실행 불가능(main도 쓰레드)
- 쓰레드는 한번에 하나의 코드라인만 수행
- 동시 처리가 필요하다면 쓰레드를 추가 생성해야 함.
우리가 웹 페이지를 만들었는데, 한번에 여러명이 웹 페이지에 접속하게 된다면... 늦게 온사람은 기다려야 한다.. 이거는 매우 비효율적이고, runtimeException이 날 수 있다 -> 멀티 쓰레드 개념이 들어옴
- 서블릿 객체를 호출하는 것 :
쓰레드
- 그런데 쓰레드가 하나면... 늦게 들어온 클라이언트는 기다려야 함...
- 여러개의 쓰레드를 이용하는
멀티 쓰레드 개념 필요

- 이렇게 쓰레드를 생성해서 동시 요청을 처리할 수 있다
- 하나의 쓰레드가 지연되도 다른 쓰레드는 정상 작동한다
- 하지만.. 쓰레드는 생성,삭제 비용이 매우 비싸다
- 고객의 요청마다 쓰레드를 생성하면, 응답 속도가 늦어진다
- 쓰레드는 컨텍트 스위칭 비용(쓰레드 전환 비용)이 발생한다
- 쓰레드 생성에 제한이 없어, cpu 메모리 임계점을 넘으면 서버는 죽는다...
-> 그래서 쓰레드 풀이라는 개념이 나온다
![업로드중..]()
- 이렇게 미리 쓰레드 풀에 쓰레드를 만들어 놓고
- 요청이 오면 사용하고 사용이 끝나면 쓰레드를 쓰레드 풀에 반납한다
- 사진의 경우 200명의 요청이 한번에 들어와도 잘 수행할 수 있다.
- 쓰레드 풀에 대기중인 쓰레드가 0개라면, 쓰레드는 연결을 대기하거나, 거절할 수 있다
- 이렇게 되면 쓰레드가 미리 생성되 있으므로, 쓰레드 생성,제거 비용(CPU)가 절약되고, 응답 시간이 빠르다
- 생성 가능한 쓰레드의 최대치가 있으므로 너무 많은 요청(200)이 들어와도 기존 요청은 안전하게 처리할 수 있다
- 하지만... 쓰레드 풀의 최대치를 잘 정해야 한다
WAS의 주요 튜닝 포인트 : 최대 쓰레드의 수
- 너무 낮으면?
동시 요청이 많으면, 서버 리소스는 여유롭지만 클라이언트는 응답 지연
- 너무 놓으면?
동시 요청이 많으면 CPU, 메모리 리소스 임계점 초과로 서버 다운
- 장애 발생시?
클라우드라면 일단 서버를 늘리고 이후에 튜닝
클라우드가 아니면 열심히 튜닝...
- 열심히 성능 테스트를 해야한다..(
아파치 ab, 제이미터, nGrinder)
<정리>
- 서블릿 컨테이너는 서블릿을 지원하는 컨테이너(톰캣 -> SpringBoot를 사용하면 서블릿 컨테이너 이용가능하다)
- 멀티 쓰레드에 대한 부분은 WAS가 알아서 처리해준다
- 개발자는 멀티 쓰레드 관련 코드 신경쓸 필요 없다
- 개발자는 마치 싱글 쓰레드 프로그래밍 하듯 편하게 코드 개발~
- 멀티 쓰레드 환경이므로 싱글톤 객체(스프링 빈, 서블릿 객체)는 항상 주의주의 또 주의!!!
- stateless 무결성...
- 절대로 필드값이 수정될 수 있게 코딩하면 안된다
<백앤드 개발자들이 서비스를 제공할 때 고민포인트 3가지...>
- 정직 리소스는 어떻게 제공할까?
- 동적으로 제공되는 HTML 페이지는 어떻게 제공할까?
- HTTP API는 어떻게 제공할까???
![업로드중..]()
<자바 백엔드 웹 기술 역사>
- Servlet
- JSP
- 서블릿+JSP 조합 MVC 패턴 사용
- MVC 프레임워크 춘추 전국시대
- 에노테이션 기반의 스프링 MVC
- 스프링 WebFlux(비동기 넌 브로킹 처리)
<자바 뷰 템플릿 역사>
- JSP
- 프리마커, 벨로시티
- Thymleaf(이걸로 수업 진행)