웹 서버란 HTTP 프로토콜을 이용하여 클라이언트의 GET, POST 등의 메소드를 활용한 요청을 서버에 전달하고 이를 서버라는 또 다른 컴퓨터가 그 요청을 처리하여 다시 클라이언트에게 반환해주는 작업이다.
요청을 받아서 연산하고 그 값을 반환하는 방식으로 하는 게 어플리케이션이다.
정적 웹 페이지는 단순히 요청을 받으면 받은 요청을 그대로 반환하는 것이다. 항상 동일한 내용을 반환하는 페이지라 생각하면 됨. (HTML, CSS, JS, 이미지 파일 등)
미리 만들어진 웹 페이지를 정적 웹 페이지라 하는데 이 페이지는 단순히 요청에 따라 그대로 반환한다.
동적 웹 페이지는 사용자의 요청에 따라 만든 페이지로 DB에서 데이터를 조회하고 페이지를 생성하여 그 사람에 맞게 만들어서 반환한다.
사용자의 입력에 따라 내용이 변경될 수 있다.
쉽게 A가 정적 페이지인 그림과 함께 글을 쓴 것이 있다고 했을 때 A가 다른 이름이나 글을 DB를 통해 데이터를 조회해서 수정한다고 했을 때 이때 정적 -> 동적이 되는 것이다.
그래서 실시간성이라는 장점이 있는 것이다.
공간 효율도 좋다. 수많은 페이지들을 웹 서버가 들고있을 필요없이 매번 만들어서 반환하면 된다.
ex) 포장 버거(정적)와 수제 버거(동적)
PHP 스크립트 언어의 한계로 Java 객체지향이 도입됨.
Java 어플리케이션 내장 웹 서버 Tomcat의 등장.
(1) 요청 → (2) 연산 (데이터 CRUD, 변수 설정, 함수 수행 등) → (3) 반환
어플리케이션이 있어야 DB와 연결이 가능.
함수와 동일하다고 생각하면 됨.
웹 서버가 요청을 받으면 어플리케이션에게 동적 웹 페이지 생성을 위임.
CGI(Common Gateway Interface) : 웹 서버가 요청을 받아 어플리케이션을 실행하고 페이지 생성을 요청하기 위한 연결고리이다. 즉 웹 서버와 어플리케이션을 연결하기 위한 기술.
프로그램이나 스크립트가 웹 서버에서 실행될 때 웹 페이지에 그 결과를 보여주는 역할을 한다. 그래서 웹 서버에서 어플리케이션이 작동하게 해서 정적인 웹 서버를 동적으로 만들어준다.
초기 CGI는 - 어플리케이션은 지금 우리가 쉽게 생각하는 Java 나 Python 이 아닌 Shell, Bash 과 같은 스크립트 언어였다. 유명한 서버 스크립트 언어로 PHP, Perl, Ruby
웹 서버안에 어플리케이션이 내장되어 있는 경우
웹 서버가 어플리케이션과 CGI로 연결되어 있는 경우 (WS + CGI + Application)
스크립트 언어의 한계로 JAVA 객체지향 프로그래밍이 도입되었다.
PHP 내장 웹 서버가 아닌 JAVA 어플리케이션에의 내장 웹 서버인 Tomcat을 사용한다.
이 WAS를 사용하면서 1요청 : 1스레드 = 서블릿 단위
가 되었다.
기존의 웹 서버의 경우 서버 혼자서 모든 로직을 수행하고 데이터를 관리하는 방식이었지만 WAS를 사용하게 되면서 서버의 일을 분담하는 방식으로 로직을 수행하게 된 것이다.
쉽게 예를 들어보자.
레스토랑에 요리사(서버)가 손님(클라이언트)으로부터 받은 음식을 요리한다고 생각하면 쉽게 기다리는 사람없이 요리가 가능하다. 하지만 100명, 1000명의 손님이 있다면 요리사 한 명으로는 손님들의 주문을 다 받을려면 많은 손님들이 기다리게 된다.
그래서 손님들이 기다리게 하지 않기 위해서는 요리사 또한 여러 명이 존재해야 한다. 그래서 웹 서버가 메인 요리사(역할 분배, 주문 확인)가 될 것이고 WAS가 실제 요리를 하는 사람이 되는 것이다.
무상태성 Stateless
정의: 서버가 클라이언트의 상태를 보존하지 못하는 것.
과거에 내가 무엇을 했는지 모르는 것처럼 기억하지 못하는 상태이다. 그래서 매번 요청마다 새로운 맥락(환경, 정보, 상태)에서 수행한다.
ex) 한 사람이 5개의 질문 요청을 한다고 가정할 때 매번 누구인지 자기소개 받고 답변 진행.
- 장점: 서버 확장성 높음
- 단점: 클라이언트가 추가 데이터를 전송
상태성 Stateful
내가 무엇을 했는지 확실히 기억하고 있는 상태이다. 매번 요청을 해도 같은 맥락에서 수행한다.
ex) 자기 소개 받아서 기억하고 있으니 답변만 바로 진행.
새로운 예시를 들어보자
Stateful
Stateful, 점원이 중간에 바뀜.
쉽게 말하면 다른 점원으로 바뀌면 장애가 나는 것이다.
서비스 개발하는 입장아리면 다른 점원 입장에서 뭔지를 몰라 본인이 원하는 데이터가 없다고 볼 수 있다.
그래서 중간에 다른 점원으로 바뀌면 상태 정보를 다른 점원에게 미리 알려줘야 한다.
Stateless
Stateless, 점원이 중간에 바뀜.
쉽게 고객이 필요한 데이터를 그때그때 다 넘기기 때문에 점윈이 바뀌어도 문제가 없다.
갑자기 클라이언트 요청이 증가해도 서버를 대거 투입할 수 있다.
갑자기 고객이 증가해도 점원을 대거 투입할 수 있다.
무한한 서버 증설 가능. 즉 무상태는 응답 서버를 쉽게 바꿀 수 있다.
상태성과 무상태성은 프로세스와 스레드와는 전혀 관련이 없다.
Stateful의 경우 클라이언트A가 요청을 보내면 항상 같은 서버가 유지되어야 한다. 서버에서 어떤 노트북인지 몇개인지 뭘로 구매할건지 정보가 계속 유지되어야 하는 것이다.
그래서 클라이언트A는 서버 1번과만 통신해야 하기 때문에 서버를 막 늘리기가 어렵다.
또 서버 1번이 장애가 나면 클라이언트A는 또 처음부터 다시 요청하고 결제해야 한다.
그에 비해 Stateless는 애초에 요청할 때부터 필요한 데이터를 다 담아서 보낸다.
그래서 상태를 보관하지 않고 그냥 필요하면 응답만 한다.
모든 것을 무상태로 설계할 수 있는 경우(이벤트 소개)도 있고 없는 경우(로그인)도 있다.
로그인한 사용자라면 그 상태를 서버에 유지해야 한다.
그렇지만 이 한계를 브라우저 쿠키와 세션 등을 통해서 유지가 가능하다.
하나 더 데이터를 너무 많이 보내야 한다.
1 요청 : 1 스레드 -> 상주 프로세스의 상태성 장점과 비상주 프로세스의 장점을 스레드를 통해 얻어냄.
서블릿과 JSP가 실행할 수 있는 환경을 제공하여 동적인 페이지를 생성한다. 클라이언트의 요청에 유연하게 대처하기 위해 DB와 연결해 데이터를 주고받거나 데이터 조작을 하여 동적인 페이지를 생성해 응답하기 위해 WAS를 사용한다.
WS에서는 클라이언트의 요청이 왔을 때만 응답했고 정적인 데이터만 처리했다. (HTML, CSS, 이미지 등)
스레드 풀 (Thread Pool) : 몇개의 스레드를 만들어놓고 대기시킬지 개수를 지정해놓는다.
Servlet 서블릿 : 1 요청에 대해 할당되는 1 자바 스레드는 서블릿이라 불린다.
Servlet Container 서블릿 컨테이너 : 요청이 오면 갖고있는 스레드를 할당하고, 완료 뒤 회수하는 주체
Q1. 웹 클라이언트가 웹 서버에게 데이터를 요청하는 상황을 가정했습니다. 이때 관점에 따라 역할이 상대적으로 바뀐다고 구글링을 통해 알게되었습니다.
A가 사용자인 관점
웹 클라이언트 = A(사용자)
네이버 같은 브라우저
브라우저가 사용자인 관점
웹 클라이언트 = 웹 브라우저
웹 서버 = 아파치, nginx
A1.
클라이언트 : 서비스를 요청하는 주체(사람이든, 서버든 뭐든)
서버 : 서비스를 제공(반환)하는 주체(사람이든, 서버든 뭐든)
Q2. client – Web Server –WAS – DB
어떤 경우에 사용되는 것인지 궁금합니다.
A2. 동적 웹 페이지의 단점이라고 하면 매번 새로운 페이지들을 만들어서 반환해야 한다는 것이죠. 아무리 SEO 와 실시간성을 중요시 여긴다고하지만, WAS 는 많이 힘들어 할겁니다.
심지어 내 블로그 글이 너무나도 인기가 많아져서 1년에 10명 들어오던 글이 갑자기 1시간에 1만명이 들어오는 기염을 토하는 상황이라면, 이야... WAS 는 1시간에 1만번 거의 같은 페이지를 매번 만들어야하는 절망적인 상황에 놓이게 됩니다 😂
해당 글을 정적 웹 페이지로 하자니 몇일마다 변경이 일어날것은 같고, 1시간에 글의 정보가 바뀔거같진 않다는 판단이 드니 머리가 아플 지경입니다.
이때 캐싱을 사용합니다.
웹 서버는 정적 웹 페이지를 서비스한다고 배웠죠.
그러면 WAS 는 자기 앞에 웹 서버를 둔뒤 웹 서버에게 잠깐 내가 반환하려는 이 동적 웹 페이지를 1시간동안 네가 정적 웹 페이지처럼 소중히 갖고 반환해줘 나 라면 좀 먹고올게 라고 심부름을 시킵니다.
결과
WS : WAS 의 업무를 완화하기 위해 잠깐동안 동적 웹 페이지를 정적 웹 페이지로 저장해서 반환
WAS : 동적 웹 페이지 렌더의 부담을 완화 (나가서 라면먹고 올수있음)
Reference
🔗 WEB(아파치)과 WAS(톰캣) 차이
🔗 https://80000coding.oopy.io/2352c04e-8f98-4695-a5fe-8c789ee94d98 - 웹 서버와 WAS, CGI