웹서버, 웹 어플리케이션 서버

Park sang woo·2023년 12월 29일
0

📓 WS(웹 서버), WAS(웹 어플리케이션 서버)

웹 서버란 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




📓 WAS

🏷️ WAS 2가지 형태 (동적 웹 페이지를 제공하기 위한 방법)

  1. 웹 서버안에 어플리케이션이 내장되어 있는 경우

  2. 웹 서버가 어플리케이션과 CGI로 연결되어 있는 경우 (WS + CGI + Application)


스크립트 언어의 한계로 JAVA 객체지향 프로그래밍이 도입되었다.
PHP 내장 웹 서버가 아닌 JAVA 어플리케이션에의 내장 웹 서버인 Tomcat을 사용한다.

이 WAS를 사용하면서 1요청 : 1스레드 = 서블릿 단위
가 되었다.

기존의 웹 서버의 경우 서버 혼자서 모든 로직을 수행하고 데이터를 관리하는 방식이었지만 WAS를 사용하게 되면서 서버의 일을 분담하는 방식으로 로직을 수행하게 된 것이다.


쉽게 예를 들어보자.
레스토랑에 요리사(서버)가 손님(클라이언트)으로부터 받은 음식을 요리한다고 생각하면 쉽게 기다리는 사람없이 요리가 가능하다. 하지만 100명, 1000명의 손님이 있다면 요리사 한 명으로는 손님들의 주문을 다 받을려면 많은 손님들이 기다리게 된다.
그래서 손님들이 기다리게 하지 않기 위해서는 요리사 또한 여러 명이 존재해야 한다. 그래서 웹 서버가 메인 요리사(역할 분배, 주문 확인)가 될 것이고 WAS가 실제 요리를 하는 사람이 되는 것이다.






📓 상태성과 무상태성

무상태성 Stateless
정의: 서버가 클라이언트의 상태를 보존하지 못하는 것.
과거에 내가 무엇을 했는지 모르는 것처럼 기억하지 못하는 상태이다. 그래서 매번 요청마다 새로운 맥락(환경, 정보, 상태)에서 수행한다.
ex) 한 사람이 5개의 질문 요청을 한다고 가정할 때 매번 누구인지 자기소개 받고 답변 진행.

- 장점: 서버 확장성 높음
- 단점: 클라이언트가 추가 데이터를 전송

상태성 Stateful
내가 무엇을 했는지 확실히 기억하고 있는 상태이다. 매번 요청을 해도 같은 맥락에서 수행한다.
ex) 자기 소개 받아서 기억하고 있으니 답변만 바로 진행.



새로운 예시를 들어보자
Stateful

  • 고객: 이 노트북 얼마인가요?
  • 점원A: 100만원 입니다. (노트북 상태 유지)
  • 고객: 2개 구매하겠습니다.
  • 점원A: 200만원입니다. 신용카드, 현금중에 어떤 걸로 구매하시겠어요? (노트북, 개수 2개 상태 유지)
  • 고객: 신용카드로 구매하겠습니다.
  • 점원A: 200만원 결제 완료했습니다. (노트북, 2개, 신용카드 상태 유지)

Stateful, 점원이 중간에 바뀜.

  • 고객: 이 노트북 얼마인가요?
  • 점원A: 100만원 입니다.
  • 고객: 2개 구매하겠습니다.
  • 점원B: 무엇을? 2개 구매하시겠어요?
  • 고객: 신용카드로 구매하겠습니다.
  • 점원C: 무슨 제품을? 몇 개? 신용카드로 구매하시겠용?

쉽게 말하면 다른 점원으로 바뀌면 장애가 나는 것이다.
서비스 개발하는 입장아리면 다른 점원 입장에서 뭔지를 몰라 본인이 원하는 데이터가 없다고 볼 수 있다.
그래서 중간에 다른 점원으로 바뀌면 상태 정보를 다른 점원에게 미리 알려줘야 한다.


Stateless

  • 고객: 이 노트북 얼마인가요?
  • 점원A: 100만원 입니다.
  • 고객: 노트북 2개 구매하겠습니다.
  • 점원A: 노트북 2개는 200만원입니다. 신용카드, 현금중에 어떤 걸로 구매하시겠어요?
  • 고객: 노트북 2개를 신용카드로 구매하겠습니다.
  • 점원A: 200만원 결제 완료했습니다.

Stateless, 점원이 중간에 바뀜.

  • 고객: 이 노트북 얼마인가요?
  • 점원A: 100만원 입니다.
  • 고객: 노트북 2개 구매하겠습니다.
  • 점원B: 노트북 2개는 200만원입니다. 신용카드, 현금중에 어떤 걸로 구매하시겠어요?
  • 고객: 노트북 2개를 신용카드로 구매하겠습니다.
  • 점원C: 200만원 결제 완료했습니다.

쉽게 고객이 필요한 데이터를 그때그때 다 넘기기 때문에 점윈이 바뀌어도 문제가 없다.
갑자기 클라이언트 요청이 증가해도 서버를 대거 투입할 수 있다.
갑자기 고객이 증가해도 점원을 대거 투입할 수 있다.
무한한 서버 증설 가능. 즉 무상태는 응답 서버를 쉽게 바꿀 수 있다.

상태성과 무상태성은 프로세스와 스레드와는 전혀 관련이 없다.


🏷️ 이제 클라이언트와 서버와의 관계로 생각해보자.

Stateful의 경우 클라이언트A가 요청을 보내면 항상 같은 서버가 유지되어야 한다. 서버에서 어떤 노트북인지 몇개인지 뭘로 구매할건지 정보가 계속 유지되어야 하는 것이다.
그래서 클라이언트A는 서버 1번과만 통신해야 하기 때문에 서버를 막 늘리기가 어렵다.
또 서버 1번이 장애가 나면 클라이언트A는 또 처음부터 다시 요청하고 결제해야 한다.

그에 비해 Stateless는 애초에 요청할 때부터 필요한 데이터를 다 담아서 보낸다.
그래서 상태를 보관하지 않고 그냥 필요하면 응답만 한다.

🏷️ Stateless 한계

모든 것을 무상태로 설계할 수 있는 경우(이벤트 소개)도 있고 없는 경우(로그인)도 있다.

로그인한 사용자라면 그 상태를 서버에 유지해야 한다.
그렇지만 이 한계를 브라우저 쿠키와 세션 등을 통해서 유지가 가능하다.

하나 더 데이터를 너무 많이 보내야 한다.



  • CGI 초기 = 1 요청 : 1 비상주 프로세스
    • 매번 요청에 따라 프로세스가 실행되고 웹 페이지 만들고 반환하고 죽는다
      • 라면 식당 비유를 하자면, 라면 먹을때마다 식당 문열고 불키고 .. 6개 작업을 다 수행하는것
    • Stateless 비상태성 : 매 요청마다 새로운 프로세스가 생성-실행(반환)-죽음 이기에 요청 간 정보 없음
      • 어제 실행된 프로세스랑 오늘 실행된 프로세스는 독립적

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

### 🏷️ 라면 식당 비유는 프로세스와 스레드에서의 내용을 다시 볼 것.




📓 WAS (Tomcat)

1 요청 : 1 스레드 -> 상주 프로세스의 상태성 장점과 비상주 프로세스의 장점을 스레드를 통해 얻어냄.

  • 하나의 요청이 들어오면, 하나의 스레드가 해당 요청에 생성 및 할당

🏷️ Tomcat

서블릿과 JSP가 실행할 수 있는 환경을 제공하여 동적인 페이지를 생성한다. 클라이언트의 요청에 유연하게 대처하기 위해 DB와 연결해 데이터를 주고받거나 데이터 조작을 하여 동적인 페이지를 생성해 응답하기 위해 WAS를 사용한다.

WS에서는 클라이언트의 요청이 왔을 때만 응답했고 정적인 데이터만 처리했다. (HTML, CSS, 이미지 등)


스레드 풀 (Thread Pool) : 몇개의 스레드를 만들어놓고 대기시킬지 개수를 지정해놓는다.

Servlet 서블릿 : 1 요청에 대해 할당되는 1 자바 스레드는 서블릿이라 불린다.

Servlet Container 서블릿 컨테이너 : 요청이 오면 갖고있는 스레드를 할당하고, 완료 뒤 회수하는 주체






❓❓ 질문 사항

Q1. 웹 클라이언트가 웹 서버에게 데이터를 요청하는 상황을 가정했습니다. 이때 관점에 따라 역할이 상대적으로 바뀐다고 구글링을 통해 알게되었습니다.

  • A가 사용자인 관점
    웹 클라이언트 = A(사용자)
    네이버 같은 브라우저

  • 브라우저가 사용자인 관점
    웹 클라이언트 = 웹 브라우저
    웹 서버 = 아파치, nginx


A1.
클라이언트 : 서비스를 요청하는 주체(사람이든, 서버든 뭐든)
서버 : 서비스를 제공(반환)하는 주체(사람이든, 서버든 뭐든)


ex)
  • 식당에서 : 클라이언트 = 손님 / 서버 = 음식을 서빙해주는 사람
  • 웹 페이지를 보는 관점에서 : 클라이언트 = 웹 브라우저 / 서버 = 웹 서버
  • 웹 내 정보를 주고받는 관점에서 : 클라이언트 = 결제 웹 서버 / 서버 = 유저 웹 서버



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

profile
일상의 인연에 감사하라. 기적은 의외로 가까운 곳에 있을지도 모른다.

0개의 댓글