대부분이 HTTP 기반으로 움직이는 웹, 서버간에 데[이터를 주고 받을 때도 HTTP를 사용한다.
-웹 서버와 웹 애플리케이션 서버(WAS)

웹 서버
-HTTP 기반으로 동작한다.
-정적 리소스 제공, 기타 부가기능
- 정적 HTML, CSS, JS, 이미지, 영상 등을 제공하는 역할.
- NGINX, APACHE 등이 예시

웹 애플리케이션 서버 (WEB -APPLICATION - SERVER)
-HTTP 기반으로 동작
-웹 서버 기능 포함 + (정적 리소스 제공 가능)
-프로그램 코드를 실행해서 애플리케이션 로직 수행
- 동적 HTML / HTTP API (JSON) / 서블릿 /JSP /스프링 MVC
- 톰켓, Jetty, Undertow 가 그 예시
웹 서버와 웹 애플리케이션 서버(WAS) 의 차이점을 말하자면,
-웹 서버는 "정적 리소스 파일", WAS는 애플리케이션 로직 위주의 동작을 수행한다.
-하지만 용어의 경계가 애매한 부분이 있어, 웹 서버도 프로그램 실행 기능을 포함하고, WAS도 웹 서버의 기능을 제공함
-다만 WAS가 애플리케이션 코드를 실행하는데 더 특화되어 있다.
때문에

이처럼 WAS와 DB 만으로도 시스템 구성이 가능하다.
(WAS가 정적 리소스, 애플리케이션 로직 모두 제공이 가능하기 때문)
하지만 실질적으로는 WAS가 너무 많은 역할을 담당해서 서버 과부하 우려가 있기 때문에 그렇게 하지는 않는다.
애플리케이션 코드 (=동적 리소스, 수행값이 더 비쌈)를 수행해야하는데, 정적 리소스 때문에
정작 중요한 애플리케이션 코드가 수행되지 않을 수도 있기 때문이다.
그래서

웹 서버 = HTML ,CSS, 이미지 등 정적 리소스를 관리 및 처리.
웹 어플리케이션 = 웹 서버에서 동적인 처리가 필요하면 WAS에 요청을 위임.
-> 즉 WAS는 중요한 애플리케이션 로직만을 처리 전담.
이렇게 해서 만약 정적 리소스가 많다 . -> 웹 서버 증설
애플리케이션 리소스(동적 리소스)가 많다 -> WAS 증설
만약 오류시에는

사실 정적 리소스만 제공하는 웹 서버는 잘 죽지 않는데,
애플리케이션 로직은 복잡도가 상대적으로 높기 때문에 WAS 서버는 잘 죽는다.
그래서 만약 WAS 또는 DB가 죽거나 오류가 생길 경우, 웹 서버에서 오류화면 HTML을 띄어준다.
서블릿
서블릿에 대해서 말하기 전에, HTTP 통신 방식에 대해서 알아볼 필요가 있다.

만약 이처럼 username: kim / age: 20으로 서버에 POST 했다면,
웹 브라우저에서 오른쪽과 같은 요청 HTTP 메시지를 보낼 것이다.
그럼 만약 서블릿이 없다는 가정하에서는

서버 TCP/IP 연결, 소켓 연결부터 ~TCP/IP에 응답 전달, 소켓 종료까지의 모든 절차를 개발자가 일일이 구현해야한다.
HTTP 요청 메시지를 받으면 POST 인지 Content-Type은 뭔지, 메시지 바디에는 어떤 내용이 담겨서 왔는지,
이 모든 부분을 개발자가 파싱해서 데이터를 사용해야한다. (상상만해도 두려운 일이다)
하지만, 정작 제일 중요한 로직은 비즈니스 로직 실행하는 부분이다.
때문에 서블릿을 사용하는 것인데, 서블릿을 사용하면 비즈니스 로직 실행부분을 제외한 나머지들을 모두 지원해준다.

urlPatterns의 /hello URL이 호출되면 서블릿 코드가 실행되는데
이 중 service 메서드의 HttpServletRequest, HttpServletResponse가 요청/응답 정보를 편리하게 사용할 수 있게한다.
예를 들어
HttpServletRequest 인터페이스의
-getMethod()를 통해, Http 요청의 메서드 (GET,POST)등을 확인할 수 있고,
-getHeader(String name) 메서드를 통해 특정 헤더의 값을 가져올 수도 있다.
이외에도 getParameter, getSession등의 메서드등도 존재한다.
이후,

웹 브라우저에서 localhost:8080/hello로 request를 보내면 WAS에서는 HTTP 요청 메시지를 기반으로
request와 respose 객체를 생성하고, 이 객체들을 파라미터로 넘겨서 방금 만든 helloServlet을 실행시킵니다.
(애플리케이션 로직등이 실행이 되겠죠?) 그리고 반환하면 다시 response 객체 정보를 기반으로 HTTP 응답 메시지를 만듭니다.
-정리-
HTTP 요청시
->WAS는 Request, Response 객체를 새로 만들어서 서블릿 객체 호출
• 개발자는 Request 객체에서 HTTP 요청 정보를 편리하게 꺼내서 사용
• 개발자는 Response 객체에 HTTP 응답 정보를 편리하게 입력
• WAS는 Response 객체에 담겨있는 내용으로 HTTP 응답 정보를 생성
-마지막으로 response 객체가 웹 브라우저로 반환되어서 웹 브라우저에서는 html을 렌더링해서 클라이언트에게 보여줌.
그리고 서블릿 컨테이너는
-톰캣처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 하는데,
서블릿 컨테이너는 서블릿 객체를 생성,초기화,호출,종료까지 생명주기 관리를 해줍니다.
-서블릿 객체는 싱글톤으로 관리가 됩니다. (helloServlet은 싱글톤)
-동시 요청을 위한 멀티 쓰레드 처리를 지원합니다.
멀티 쓰레드

웹에서 WAS로 서블릿을 호출한다면 서블릿 객체를 호출해주는 대상이 있을것이다.
이것이 바로 "쓰레드"인데
쓰레드는 애플리케이션 코드를 하나하나 순차적으로 실행해주는 것이다.
예를 들면 자바 메인 메서드를 처음 실행하면 main이라는 이름의 쓰레드가 실행된다.
만약 쓰레드가 없다면 자바 애플리케이션도 실행이 불가능할 것이다.
쓰레드는 한번에 하나의 코드 라인만 수행하기 때문에, 동시 처리가 필요하면 쓰레드를 추가로 생성해야한다.

만약 그 쓰레드가 하나라면, WAS에서 서블릿을 호출할 대상도 하나이고,
요청이 하나 들어오면 쉬고있던 쓰레드가 서블릿 객체를 호출하기 위해 할당될 것이다.
그리고 응답이 끝나면 다시 쓰레드는 휴식 상태로 돌아간다.
하지만 만약 한 번에 요청이 여러개 들어온다면?

하나의 쓰레드가 여러 요청을 감당하게 된다면, 하나의 요청 처리중에는 다른 요청을 받아드릴 수 없으므로
타 요청은 쓰레드가 일이 끝날때까지 대기하게 된다. 설상가상으로 요청 1의 처리가 지연된다면,
결국에는 타임아웃과 같은 문제등으로 오류가 발생해서 요청1,2 둘 다 죽게된다.
그럼 해결법은?

간단하게, 쓰레드를 더 만들어버리면 된다.
요청이 들어오면 쓰레드를 만들어버리면 되는 문제이다.
하지만 이 역시도 장단점이 존재하는데
요청마다 쓰레드 생성
장점
• 동시 요청을 처리할 수 있다.
• 리소스(CPU, 메모리)가 허용할 때 까지 처리가능
• 하나의 쓰레드가 지연 되어도, 나머지 쓰레드는 정상 동작한다
단점
• 쓰레드는 생성 비용은 매우 비싸다.
• 고객의 요청이 올 때 마다 쓰레드를 생성하면, 응답 속도가 늦어진다.
• 쓰레드는 컨텍스트 스위칭 비용이 발생한다.
• 쓰레드 생성에 제한이 없다.
• 고객 요청이 너무 많이 오면, CPU, 메모리 임계점을 넘어서 서버가 죽을 수 있다.
무제한 찍어내면 간단한 일이겠지만 , 자원이라는 것이 존재하기 때문에
생성 비용이 비싼 쓰레드를 찍어내면 CPU,메모리 등의 자원 문제로 서버가 죽을 수도 있다.
또한 컨텍스트 스위칭 비용이라는 것이 있는데,
예를 들어 내 컴퓨터의 코어가 1개이고, 쓰레드를 2개 사용하고 있다면,
코어는 쓰레드 1개를 사용하고, 다른 쓰레드로 전환하여 요청을 처리한다.
우리가 체감하기에는 그 전환속도가 너무 빨라서 마치 2개를 동시에 처리하고 있는 것 처럼 보이는데
사실 여러 쓰레드를 전환하면서 사용하고 있는 것이다.
그래서 쓰레드가 많아지면 컨텍스트 스위칭 비용도 늘어나게 되고 이 역시도 자원문제를 겪게된다.
해결법

요청마다 쓰레드를 생성하는 것이 아니라 필요한 쓰레드를 쓰레드 풀에 보관하고 관리하는 방법이다.
쓰레드 풀에 생성 가능한 쓰레드의 최대치를 관리한다. (톰캣은 최대 200개 기본 설정)
그리고 쓰레드가 필요하면, 이미 생성되어 있는 쓰레드를 쓰레드 풀에서 꺼내어 사용한다.
사용을 종료하면 쓰레드 풀에 해당 쓰레드를 반납한다.
최대 쓰레드 모두 사용중이어서 쓰레드 풀에 쓰레드가 없으면?
->요청을 거절하거나 특정 숫자만큼은 대기열에 대기하도록 설정할 수 있다.
이렇게하면 쓰레드를 생성하고 종료하는 비용도 절약되고 응답 시간도 빨라진다.
또한 쓰레드 최대치도 정해놓았으므로 많은 요청이 들어와도 기존 요청에는 지장없이 처리할 수 있다.
쓰레드 풀 값 설정
->너무 낮게 설정하면 = 동시 요청이 많을 경우, 서버 리소스는 여유롭지만 클라이언트 응답이 지연된다.
->너무 높게 설정하면 = 동시 요청이 많을 경우, CPU,메모리 리소스 임계점 초과로 서버가 다운된다.
-->애플리케이션 복잡도, CPU, 메모리등 리소스 상황에 따라서 적정 숫자를 찾아야한다.
-->또는 실제 서비스와 비슷하게 성능 테스트를 시도해본다.
아무튼 WAS는 멀티 쓰레드를 지원하기 때문에 개발자가 멀티 쓰레드 관련 코드를 신경쓰지 않아도 된다.
정적 리소스
고정된 HTML, CSS, JS, 이미지 영상 등을 제공
-주로 웹 브라우저

URL로 요청이 들어오면 웹 서버에서는 이미 있는 리소스 파일을 반환해주는 간단한 리소스입니다.
HTML 페이지
동적인 HTML 페이지의 경우에서는
WAS가 데이터베이스를 통해서 조회를 하고 동적으로 HTML을 생성합니다.
JSP/타입리프 등을 이용하여 코드를 보고 HTML을 생성해서 웹 브라우저에게 반환하고
웹 브라우저는 이를 보고 해석해서 나타냅니다

HTTP API
HTML이 아니라 데이터를 전달하는 형식으로
주로 많이 들어본 JSON 형식을 사용합니다.

이 역시도 WAS에서 DB를 조회하고 DATA를 JSON 형식으로 맞춰서 웹 브라우저에 반환합니다.
다만 데이터만 주고 받기 때문에 UI 화면이 필요하면 "클라이언트"에서 별도로 처리가 필요합니다.
앱 클라이언트(아이폰,안드로이드,PC) 는 모두 연동가능하고 ,
웹 브라우저에서 자바스크립트를 통한 HTTP API 호출도 가능합니다.
이 때 "자바스크립트를 통한 HTTP API 호출"이 발전된 것이 React, Vue.js와 같은 웹 클라이언트가 됩니다.
SSR -서버 사이드 렌더링
SSR이란 서버 사이드 렌더링이라는 뜻으로
"서버에서 최종 HTML을 생성해서 클라이언트에게 전달"하는 것을 말합니다.

웹 브라우저에서 요청이오면, 서버에서 DB를 조회하고 JSP나 타임리프을 이용하여 동적으로 HTML을 생성해서
서버 측에서 HTML까지 응답으로 만들어서 웹 브라우저에 반환하는 것 입니다.
그러면 웹 브라우저에서는 HTML을 단순히 보여주기만 하면 됩니다.
CSR - 클라이언트 사이드 렌더링
-CSR은 클라이언트 측에서 웹 페이지를 동적으로 생성하고 표시하는 방법입니다.

만약 주문과 관련된 앱이라면, 먼저 웹 브라우저에서 서버로 HTML을 요청합니다.
1.서버에서는 텅 빈 HTML을 보내줍니다. 대신 자바스크립트 링크를 실어서 보내주는데,
2.그러면 웹 브라우저는 다시 자바스크립트를 요청합니다 .
3. 서버에서는 자바스크립트 코드와 클라이언트 로직/ HTML을 어떻게 렌더링 해야하는지도 보내줍니다.
4. 웹 브라우저는 그 중 클라이언트 로직 중 HTTP API를 보고 데이터를 요청합니다.
5. 서버는 요청한 HTTP API 데이터를 JSON으로 정리해서 보내줍니다.
6. 웹 브라우저는 이제 이 코드들과 JSON 데이터를보고 HTML 결과를 렌더링 합니다.
백엔드 입장에서는 사실 서버 사이드 렌더링 (SSR)은 필수적으로 학습이 필요합니다.
JSP, 타임리프등의 기술을 이용하는데 화면이 정적이고 복잡하지 않기 때문에 금방 배울 수 있다고 합니다.
반면 CSR은 우리가 흔히 얘기하는 프론트 엔드 영역이기 때문에 백엔드 입장에서는 필수는 아니고 옵션정도 입니다.