WAS와 웹서버

김민우·2022년 8월 22일
0

잡동사니

목록 보기
7/22

WAS와 웹서버의 개념을 정리해보았다. 간단히 알아보자.

일단 서버의 개념을 짚고가자. 서버는 컴퓨터라고 생각하자.
같은 컴퓨터도 서비스를 해주느냐 제공받느냐에 따라 서버와 클라이언트로 나뉜다.
서버는 다른 의미로도 사용이 되는데 어떤 컴퓨터로 하여금 서버 역할을 하도록 해주는 소프트웨어를 XX서버라고 부르기도 한다.
(우리 같은 백엔드 개발자가 서버를 개발한다고 하는데 이러한 서버도 소프트웨어의 개념이다. 아파치나 NginX가 대표적이다.)


웹서버

웹 브라우저가 읽을 수 있는 파일들(HTML, CSS, 자바스크립트), 각종 이미지, 여러 데이터들을 갖다가 서버에서 사용자의 컴퓨터로 보내줄 수 있어야 한다. 이러한 파일들은 원래 서버 컴퓨터에 저장이 되있다.

이 서버의 특정 폴더, 디렉토리에 이것들을 넣어두면 이 폴더를 외부에서 접근 가능하도록 개방해서 서버에 지정된 웹사이트 주소로 접속하면 이것들을 받아갈 수 있도록 하는 것이 웹 서버의 기본적인 역할 중 하나이다.

아파치, NginX, IIS가 대표적인 웹 서버이다. 윈도우로 서버를 돌리는 것이 아니면 아파치, NginX 둘 중 하나를 사용한다.

즉, 이 프로그램들을 사용하여 어떤 폴더를 개방을 하여 거기 들어있는 HTML 등의 파일들로 웹 사이트를 제공할 수 있다.

그러나, 이렇게 제공하는 방식은 정적 이다. 자세한 건 정적웹 동적웹을 찾아보자.

참고

  • 정적 웹
    • 블로그 페이지나 회사 소개 페이지 처럼 그 안의 내용이 바뀔 일이 없는 웹페이지들을 고정된 HTML, CSS, 자바스크립트로 제공하는 방식이다.
    • 완제품들을 갖다놓은 편의점 진열대라고 생각하자.
  • 동적 웹
    • 게시판 페이지처럼 항상 같은 내용이 뜨는게 아닌 사이트
    • 누군가 글을 올리거나 댓글을 달면 사이트 내용이 바뀌므로 고정된 HTML파일만으로 제공할 수 없다.
    • 사용자가 접속할 때 마다 페이지 내용이 동적으로 변경되어야 한다.
    • 요리사가 바로바로 음식을 만들어주는 식당이라 생각하자.

이러한 동적 웹을 제공하는 것을 웹서버의 고유 역할로 정의해야 할지는 애매하지만 아파치나 NginX의 모듈로 할 수 있다. (아파치와 PHP, MySQL을 연동시켜서 동적인 PHP 웹사이트를 제공하는 방식, 이를 APM이라 부른다. 물론 NginX로도 가능하다.)

ARM
아파치에 PHP를 해석할 수 있는 모듈을 세팅해놓으면 웹 접근이 있을 때 마다 PHP 코드에 적힌 레시피대로 MySQL에 있는 식재료들을 가져와서 아파치가 요리를 해준다고 생각하자.

또한, 톰캣이나 Node.js, Django 내장 서버와 클라이언트 사이에서 서빙이나 메니지먼트를 담당하기도 한다.

아파치, NginX

아파치는 오래전부터 널리 사용되오던 것이고 NginX는 나중에 생겼다.
이 둘은 작동방식에 있어 근본적인 차이가 있다.

아파치

  • 다중 프로세스
  • MPM(멀티 프로세스 모듈) 방식으로 작동
    • 요청이 올 때 마다 프로세스를 새로 생성하는 방식 (mpm_prefork)
      (손님이 새로 올 때마다 상담 테이블을 따로 가져와서 앉히고 이 테이블들을 계속 돌아다니면서 여러 손님들을 동시에 상대한다 라고 생각하자.)
    • 요청이 올 때 마다 한 프로세스 안에서 스레드를 새로 생성하는 방식 (mpm_worker)
      (가로로 길다란 테이블을 하나 두고, 손님이 올 때마다 나란히 앉힌 다음 좌우로 돌아다니면서 동시에 업무를 처리하는 것이라 생각하자.)
  • 이러한 방식은 컨텍스트 스위칭이 발생하면서 컴퓨터 자원을 많이 소모한다.

NginX

  • 이벤트로 일을 처리한다.
  • 작은 데스크 하나만 두고 손님들을 한 줄로 쭉 세운다. 그 후 다음 손님이 오는 대로 업무별로 집중해서 일을 처리한다.
  • 성능적인 측면에서 아파치보다 좋다.
  • 이러한 이벤트로 일을 처리하는 방식은 아파치에도 추가가 됬다.

요약하자면 다음과 같다.

성능과 가벼움을 중요시하는 서비스 -> NginX
다양하고 검증된 기능들을 필요로 하는 곳 -> 아파치 (오랜 기간 사용됬으므로 안정적임)


WAS (Web Application Server)

자바랑 JSP로 만든 웹 또는 API 어플리케이션을 실행할 때 사용이 된다. 단어 그대로 '웹'이랑 '서버'사이에 단순히 뭔가를 갖다주는 것이 아니라 뭔가 프로그래밍된 걸 더 한다는 뜻이다. 이는 동적 사이트를 전문적으로 처리해주는 것이라 생각하자.

그러나, 웹서버에서 동적 사이트를 처리를 할 수는 있었다. 근데 별도로 동적 사이트를 전문으로 처리하는 WAS를 사용하는 것일까?

아파치나 NginX같은 웹서버에서도 PHP같은 종류를 처리할 수는 있지만 처리하기 힘든(?) 스프링같은 전문적인 것으로 넘어가면 WAS를 사용해야 한다.

마치 일반 분식집을 운영하는 사람(웹서버)에게 일식 전문 요리(스프링 등...)를 만들라하면 꽤나 난처할 것이다. 이는 일식을 전문으로하는 요리사(WAS)에게 부탁해야한다.

이러한 WAS들 중 자바 바이트코드로 컴파일 되는 언어들에 쓰이는 걸로 가장 흔히 사용되는 톰켓이나 Jetty, Undertow 등이 있다.

이러한 WAS의 개념은 정의하기 나름이고 진영마다 배포 구조들도 달라서 자바 외의 진영에서는 딱히 어떤 것이 WAS의 역할이다 이렇게 딱히 구분해서 용어를 쓰지는 않는 걸로 보인다. (파이썬 같은 경우 Gunicorn이 비슷할 수 있는데 이거는 WSGI라는 좀 다른 개념으로 정의가 되고, Node.js에서처럼 어플리케이션이 WAS 역할까지 하거나 ...)

공통적인 것은 웹 서버를 앞단에 두고 즉, 방문자들을 이 웹서버가 응접실에서 접대하도록 하고 그 뒤에서 WAS든 뭐라 부르든 전문 요리사가 요리를 하고 있다고 생각하자.

톰켓

스프링으로 코딩한 웹 어플리케이션을 War 파일로 빌드하면 그 안에 .class 파일들, jsp, 이미지, CSS, 자바스크립트 파일등이 압축되어있다.

톰켓을 다운받아보면 여러 폴더들과 파일들이 들어있는 하나의 폴더로 되있는데 그 중 특정 폴더에 방금 언급한 War 파일을 넣고 명령어를 실행하면 스프링 서비스가 톰켓을 사용하게 돌게 되는 것이다.

요즘은 반대로 스프링을 톰켓이 들어있는 Jar 파일로 빌드해서 배포하곤 한다.


이 둘을 다 써야 하는가?

WAS(톰켓)이 스프링같은 고난도 요리를 해주고 아파치같은 웹서버가 손님들한테 서빙을 한다고 생각하자. 물론 톰켓 등의 WAS들도 방문자들에게 직접 동적으로 요리해낸 웹을 서빙해서 갖다줄 수 도 있으며 진열돼있는 정적 리소스들을 건내주는 일도 할 수 있다. 즉, 웹 서버의 역할을 WAS가 대신 할 수 도 있다.

아니 그러면 WAS만 사용하면 되는거 아닌가? 굳이 웹 서버를 앞단에 둬야되나?

참고
예전에는 톰켓이 정적 요소들을 넘겨주는 속도가 느려서 아파치가 그것을 대신해줘야 했다. 그러나 요즘은 톰켓의 정적 리소스 제공도 빨라져 그 점에서는 차이가 없다.

아파치나 NginX가 WAS 상단에서 존재하여 정적 또는 가벼운 동적 리소스를 제공하는 것 외에 다양한 기능들을 제공한다. 하나씩 알아보자.

Reverse Proxy

프록시는 한 번쯤 들어봤을 것이다... 뭘 대신한다? 정도로 알고 있다. 일단 우리가 일반적으로 알고 있는 프록시인 Forward Proxy를 알아보자.

Forward Proxy

  • 프록시를 통해 사용자들이 사이트나 어디 접속할 때, 자기 아이피 주소를 숨기려고 중간에 프록시라는 것을 둬서 그걸 통해 데이터를 주고 받는 역할을 할 수 있다.
  • 우리 서버에 방문하는 손님들이 자기네 집 주소를 감춘다고 생각하자.
  • 대절버스를 proxy라는 정류장에서 타고오는 식이라 생각하자.

자 이제 Reverse Proxy가 뭔지 감이 올 것이다. 맞다. 기존과 반대로 손님들에게 서버의 정보를 감추는 것이다. 근데 손님들은 서버가 어딨는지 다 알고 찾아왔는데 거기에 감출 필요가 있나?

서버 또한 관리자가 보안상 내부 구조를 감출 필요가 있다. 예를 들어 정적 리소스 경로는 어딘지 톰켓 같은 동적 요소를 처리하는 경로는 어디인지...
이런 것들은 드러내지 않고 아파치나 NginX가 응접실에서 대신 손님들을 맞이하고 요리를 내온다고 생각하자.

즉, 이를 통해 서버 내부적으로 파일들이 어느 폴더에 있는지 서비스가 몇 번 포트로 돌고 있는지 등을 감추는 것이다.

어떤 웹 프레임워크든 간 WAS 상단에 아파치나 NginX같은 웹서버를 두는 이유는 이런 보안 측면에서의 이유가 크다. 웹 서버가 다양한 보안 기능을 제공하기 때문에 뭘 사용해서 웹이나 API를 만들든 간 그 앞단에는 웹서버를 둬서 방문객을 맞도록 하는 것이다.

load balancing

서버 한 대 에서 하나의 사이트를 돌릴 때 같은 사이트를 돌리는 톰켓을 여러개 두는 이유는 무엇일까?

이는 지속성을 위함이다. 스프링으로 만든 웹 등의 서비스에 새 기능을 추가해서 동적인 부분까지 업데이트 해줘야 하는 경우에는 돌던 서비스를 종료하고 다시 실행을 해줘야 한다. 짧은 순간이지만 그 동안에 사용자가 해당 서비스에 접근하면 다시 켜지고 있는 중이라 오류가 발생한다.
톰켓이나 이런 것을 여러개를 두고 서비스를 돌리게 되면 이것들을 순서대로 차례차례 업데이트를 해서 하나가 재부팅되는 동안에는 웹서버가 다른 톰켓들로 주문들을 분산해줘서, 사용자의 입장에서 서비스를 끊김없이 이용할 수 있도록 해준다. (요리사에게 화장실에 갖다올 시간을 준다고 생각하자.)

이렇듯 요청을 여러 개의 WAS에게 분산해주는 것이 바로 로드 밸런싱이다.
웹 서버를 사용하는 또다른 이유는 이러한 로드 밸런싱이 있다. (이는 리버스 프록시의 기능으로 치긴한다.)

이는, 톰켓이 여러 개 돌고 있을 때 밸런스를 맞춰주는 기능이라 생각하자. (물론, 톰켓으로 하는 자바 서비스들 뿐만 아니라 다른 종류의 WAS들도 마찬가지이다.)
손님들이 여럿 몰릴 때 여러 요리사들에게 분산해서 주문을 넣어주는 역할을 한다.

물론 앞의 예시같은 상황에서 국한되는 것이 아니라 톰켓 등의 인스턴스를 여럿 돌려서 작업을 분산시키는 것은 성능적인 측면에서도 매우 중요하다.

여튼 이러한 조건들을 감안해서 다수의 인스턴스로 서비스를 돌리고 이를 웹서버로 밸런싱하는 것이다.

캐싱(Caching)

웹서버의 또 다른 중요 기능으로 캐싱이 있다. 캐시라고 들어봤을 것이다. 캐시는 한 번 꺼내온 것을 다시 안꺼내도 되게끔 별도의 저장소에 모아두는 것이다.

여기서 말하는 캐싱은 Reverse Proxy의 캐시이다.

아까 언급한 Forward Proxy의 캐싱 기능이 사용자 관점에서 한 번 받아온 이미지 등 정적 파일이 사용자와 서버 사이에 있는 프록시 서버란 곳(정류장 수하물 센터라 생각하자.)에 쌓였다가 다음 요청때 서버까지 다시 찾아갈 필요 없이 바로 받아와지는 것이다.

그러나, 여기서의 캐시는 웹 서버가 Reverse Proxy로써 제공하는 서버 단에서의 캐시이다. 서버로 찾아오는 손님들이 자주, 반복적으로 찾을 만한 리소스들을 응접실에 쌓아뒀다가 바로 건네주는 것이다.

어느쪽이든 사용자 입장에서 빨라지는건 마찬가지이다.

.
.
.

이 외에도 웹서버는 수 많은 모듈들을 사용해서 뒷단 WAS들이 정상동작하는지 주기적으로 체크를 하는 등 서비스를 안정적이고 안전하게 돌리기 위한 다양한 기능들을 제공한다. (DB나 서버에 장애가 발생했을 때 정적 웹 페이지를 띄어주는 역할을 한다거나...)


정리

웹서버와 WAS의 역할이 겹치는 부분도 있지만 각자의 특화된 부분들을 활용하여 보안이랑 운영같은 것을 더 잘하는 웹서버가 응접실에서 손님들을 직접 상대하고 WAS나 다른 비슷한 어플리케이션들은 뒤에서 동적 요소들을 만들어내는데 집중을 한다.

0개의 댓글