1. 웹 서버(WS): 정적 웹 리소스 반환
Web
Web이란 인터넷을 기반으로 하며 정보를 공유, 검색할 수 있게 하는 서비스
웹의 3가지 요소: URL(주소), HTTP(프로토콜), HTMl(내용)
Server
클라이언트에게 네트워크를 통하여 정보나 서비스를 제공하는 컴퓨터 시스템
Web + Server
위의 두 개념을 합치면 웹 서버는 "인터넷을 기반으로 클라이언트에게 웹 서비스를 제공하는 컴퓨터"

클라이언트(웹 브라우저)에서는 웹 서버에게 주소(URL)을 가지고 규칙(HTTP)에 맞게 서버에게 요청 시, 클라이언트가 원하는 내용(HTML)을 받을 수 있다.
웹 서버에서는 클라이언트의 요청을 기다렸다가, 웹 요청(HTTP)에 대한 데이터를 만들어서 응답한다.
이처럼 미리 만들어진 웹 페이지를 단순히 요청에 따라 반환하기 때문에 정적 웹 페이지라고 한다.
- if) 문서의 양이 많아짐에 따라 웹 서버의 용량도 많이 필요해진다면?
- if) 유저 정보 페이지처럼 반복적인 템플릿에 일부 정보만 변경된다면?
- 예) 1000 명의 유저 정보 페이지 = 웹페이지 1000개
- 1 개의 유저 정보 페이지 템플릿 = 웹페이지 1 개 + 1000명 유저 정보 데이터베이스에 저장
- 반복되는 템플릿과 유저 정보를 분리한다면? 동적 웹 리소스 반환 → 웹 어플리케이션 서버 등장

2. 웹 어플리케이션 서버(WAS) : 정적 + 동적 웹 리소스 반환
이미 다 만들어진 것을 반환하는게 아닌, 요청에 따라 웹 페이지를 만드는 동적 웹 페이지
여기서 동적의 근간은 데이터이다. 웹 서버가 요청을 받으면 먼저 동적 웹 페이지를 생성한 뒤에 결과 웹 페이지를 반환한다.
- 웹 서버(WS): (1) 요청 → (2) 반환
- 웹 어플리케이션(WAS): (1) 요청 → (2) 연산 (데이터 CRUD, 변수 설정, 함수 수행 등) → (3) 반환
웹 서버가 요청을 받으면 어플리케이션에게 동적 웹 페이지 생성 작업을 위임.
- CGI(Common Gateway Interface) = 웹 서버가 요청 받아 어플리케이션을 실행하고 페이지 생성을 요청하기 위한 연결고리
- 처음 CGI 가 등장했을때 어플리케이션은 지금 우리가 쉽게 생각하는 Java 나 Python 이 아닌 Shell, Bash 과 같은 스크립트 언어였다. 유명한 서버 스크립트 언어로 PHP, Perl, Ruby

현대 웹 어플리케이션 서버 : Tomcat 의 예
- 과거 : WAS = WS + (CGI) + Application
- 현대 : WAS (내부에 Application - WAR)
+ 프로그램, 프로세스, 스레드

정적 프로그램
- 컴퓨터에서 실행 할 수 있는 파일을 통칭한다. 단, 아직 파일을 실행하지 않은 상태이기 때문에 정적 프로그램(Static Program) 줄여서 프로그램(Program)이라고 부른다.
- 코드 덩어리
프로세스(Process)
- 컴퓨터에서 연속적으로 실행되고 있는 컴퓨터 프로그램(프로그램이 돌아가고 있는 상태)
- 실행 단위가 크고 + 한개의 프로그램에 한개의 프로세스만 존재한다
스레드(Thread)
- 프로세스 내에서 동시에 진행되는 작업 갈래, 흐름의 단위
- 실행 단위가 작고 + 한개의 프로그램 (한개의 프로세스) 내 수많은 스레드가 존재가능하다.
- 1 프로그램 = 1 프로세스 라서 하나의 작업만 할 수 있는 한계를 벗어나서
1 프로세스 = N 스레드 라서 다양한 작업 + 동시 작업 이 가능하다
3. 웹 서버에서 웹 어플리케이션 서버로의 변천사
3.1. Web Server 웹 서버, WS (Apache, Nginx 등)
- CGI 초기 = 1 요청 : 1 비상주 프로세스
- 매번 요청에 따라 프로세스가 실행되고 웹 페이지 만들고 반환하고 죽는다
- Stateless(비상태성): 매 요청마다 새로운 프로세스가 생성-실행(반환)-죽음 이기에 요청 간 정보 없음
- 어제 실행된 프로세스랑 오늘 실행된 프로세스는 독립적

- FCGI = 1 요청 : 1 상주 프로세스
- 매번 요청에 따라 이미 열려있던 프로세스가 웹 페이지 만들고 반환하고, 프로세스는 계속 살아 있다
- 프로세스가 계속 상주해있으니 위 CGI 초기보다 매 프로세스 준비기간은 줄어듦
- Stateful 상태성 : 아무리 많은 요청이 와도 기존 프로세스가 실행(반환) 만 하기에 요청 간 정보 공유
- 어제 실행된 프로세스랑 오늘 실행된 프로세스는 같은 프로세스라 같은 정보 공유

3.2. Web Application Server 웹 어플리케이션 서버, WAS (Tomcat, Netty 등)
1 요청 : 1 스레드 = 상주 프로세스의 Stateful 장점과 비상주 Stateless 의 장점을 스레드를 통해 얻어냄
- 하나의 요청이 들어오면, 하나의 스레드가 해당 요청에 필요에 따라 생성 및 할당 또는 할당
- Servlet(서블릿) : 1 요청에 대해 할당되는 1 자바 스레드(WAS)는 서블릿이라 불린다
- Servlet Container(서블릿 컨테이너) : 요청이 오면 갖고있는 스레드를 할당하고, 완료 뒤 회수하는 주체

4. 웹 페이지 렌더링 방식
4.1 SSG(Static Site Generation)
다른 말로, Static-Rendering(정적 렌더링) 이라고도 하는 해당 방식은 클라이언트에서 필요한 페이지들을 사전에 미리 준비해뒀다가, 요청을 받으면 이미 완성된 파일을 단순히 반환하여 브라우저에서 뷰를 보여지게 된다..
4.2 SSR(Server-Side-Rendering): Next.js
서버에서 뷰 구성에 필요한 전체 HTML을 요청을 받은 즉시 생성해서 반환합니다. 이렇게 하면 클라이언트 브라우저에서 응답을 받은 후, 이미 완성된 뷰를 그대로 보여지게 됩니다.

- 클라이언트가 특정 페이지를 요청한다.
- 서버에서는 해당 페이지에 필요한 데이터를 포함한 HTML 파일을 클라이언트에 전달한다.
- 클라이언트에서는 해당 HTML 파일을 파싱하면서 필요한 정적 리소스(CSS, 이미지 등)와 자바스크립트 파일을 다운로드하며, 페이지를 렌더링한다. 이 때 사용자는 렌더링된 페이지를 볼 수는 있지만 아직 클릭 등의 인터렉션은 할 수 없다.
- 클라이언트에서 다운로드한 자바스크립트 파일을 실행한다.
- 페이지 인터렉션이 가능해진다.
4.3 CSR (Client Side Rendering): React.js
클라이언트 브라우저에서 어플리케이션을 렌더링을 진행합니다. 즉 어플리케이션 구동에 필요한 HTML, JS, CSS 파일 등을 모두 다운로드 한 뒤에 뷰가 구성되게 됩니다.

- 클라이언트가 특정 페이지를 요청한다.
- 서버에서는 빈 HTML 문서를 클라이언트에 전달한다.
- 클라이언트가 HTML 문서에 포함된 함께 정적 리소스(CSS, 이미지 등), 번들 자바스크립트 파일을 다운로드한다.
- 클라이언트에서 번들 자바스크립트 파일을 실행한다. 자바스크립트에 의해 페이지가 렌더링되며, 이 때 사용자는 렌더링된 페이지를 볼 수 있다. 아직 API에서 데이터를 받아오지 않았기 때문에 로딩(빈 화면) 혹은 임시 데이터가 표출된다.
- 페이지 렌더링이 완료된 후, (useEffect 내의) API 요청 코드가 실행된다.
- API에서 받아온 데이터로 state를 업데이트하고 페이지를 리렌더링한다.
- 페이지 인터렉션이 가능해진다.