🌱 해당 포스트는 한걸음 스터디에서 발표한 내용입니다. 발표 내용을 아래 영상에서 확인하실 수 있습니다.
🌱한걸음은 각자 학습한 내용을 토대로 블로그 글을 작성하고, 대면으로 모여서 발표하며, 녹화해 유튜브에 업로드하는 스터디입니다.
최대한 일반적인 사용자의 입장에서 본다면 웹을 이용한다는 것은 브라우저를 통해서 웹사이트에 들어가는 것을 말할 것입니다.
웹의 내부 구조에 큰 관심이 없는 사람들도 보통 서버(Server)의 존재에 대해 알고 있습니다. 서버가 느리다(😢). 서버가 터졌다(😨). 등의 표현이 자주 사용됩니다. 그러므로 우리는 대부분 크롬과 같은 웹 브라우저에 우리가 주소를 입력(혹은 클릭)하면 해당 주소에 대응하는 서버로부터 무언가를 받아와 우리에게 웹페이지를 보여준다는 것을 어렴풋이 알고 있습니다.
이런 식으로 누구는 무언가를 요청하고, 누구는 요청한 것을 반환하는 웹의 동작 방식을 보고 우리는 클라이언트-서버 아키텍처(Client-Server Architecture)라고 부릅니다. 우리는 결국 브라우저를 통해서 서버에 무언가를 요청하기 때문에, 지금부터는 편의상 사람과 브라우저를 하나로 묶어 클라이언트(Client)라고 부르겠습니다.
이제 여기서 무얼 받아오느냐 하는 것이 HTML(웹페이지), 이미지, 파일, JSON 등 이고, 어떻게 받아오냐 하는 것이 HTTP입니다.
클라이언트와 서버가 인터넷을 통해 어떤 데이터를 주고 받는다는 것까지는 감이 오실 겁니다. 그런데 정확히 어떤 데이터를 주고 받을까요? 클라이언트가 어떤 식으로 요청할지 모르는 상태에서는 아무것도 처리할 수가 없을 것입니다. 클라이언트 측에서도 서버가 어떤 형식의 요청 형식을 원하는지 모른다면 요청을 보내기 어려울 것입니다. 손님과 점원이 언제 어디서나 원활한 커뮤니케이션을 하기 위해서는 명확한 약속이 필요합니다.
이런 명확한 약속을 멋있는 말로 프로토콜(Protocol)이라고 합니다. HTTP는 클라이언트-서버 사이 요청-응답으로 이루어진 통신 프로토콜입니다. HTTP 안에는 미리 정의된 다양한 데이터 입력란이 있습니다. 클라이언트는 HTTP 프로토콜을 바탕으로 요청을 만들고, 마찬가지로 서버도 이를 바탕으로 메시지를 해석합니다.
클라이언트로서 계속 요청을 보내고 있는 이 추상적인 서버(Server)라는 것의 정체를 좀 밝혀보겠습니다. 요구사항에 따라 형태가 조금씩 달라질 수 있지만, 전형적인 서버의 형태는 다음과 같습니다.
우선 서버란 결국 하나(혹은 다수의) 컴퓨터라고 생각해주시면 되겠습니다. 해당 컴퓨터 안에서 우리가 보내는 HTTP 요청을 처리하고 필요한 데이터를 저장하고 가공해 다시 제공하는 일을 하기 위해 3개의 친구들이 돌아가고 있습니다. 이들이 각각 웹 서버(Web Server), 웹 애플리케이션 서버(Web Application Server, 이하 WAS), 그리고 데이터베이스(Database, 이하 DB)입니다.
우선 클라이언트가 필요한 데이터를 먼저 정의하고 가겠습니다. 우리가 브라우저 화면으로 보는 웹페이지는 보통 HTML(CSS, JS)이라는 것으로 되어 있습니다. 이는 브라우저가 데이터를 화면으로 표현하기 위해 정해진 것이라고 생각하시면 되겠습니다. 간단히 회사를 소개하는 웹사이트를 만든다고 하면, 화면에 들어가는 사진이나 내용은 사용자의 요청에 상관없이 미리 준비할 수 있습니다. 누가 언제 보든 똑같은 페이지가 나타날 것입니다.
이런 데이터를 정적 리소스라고 부릅니다. 정적 리소스는 HTML, CSS, JS, 이미지, 영상 등이 있습니다.
그런데 이제 회사 뉴스와 같은 데이터를 제공하려고 한다고 하면, 새로운 뉴스가 추가될 때마다 기존 HTML을 수정한다고 하면 아주 번거롭고 비효율적인 일이 될 것입니다. 또한 특정 데이터를 검색하거나 하는 일도 할 수 없습니다.
그래서 데이터만 따로 저장하고 이를 HTML로 필요할 때 만들어서 원하는 사람에게 제공하는 방법을 떠올립니다. 이러한 데이터를 동적 리소스라고 부릅니다.
앞으로의 설명을 위해 서버를 식당에 비유하겠습니다. 해당 식당은 이미 포장되어 있어 당장 드릴 수 있는 그랩앤고 상품이 있고, 조리가 필요한 메뉴 상품이 있습니다. 또한 조리에 쓰이는 재료를 저장하는 냉장고가 있습니다. 감이 오시겠지만 각각 정적 리소스, 동적 리소스, 데이터베이스에 해당합니다.
웹 서버(Web Server)란 HTTP를 기반으로 동작하는 서버로 정적 리소스를 제공합니다.
그 외에도 애플리케이션에 따라서 리버스 프록시, 로드벨런싱 등 다양한 부가 기능을 지원하지만 주로 HTTP 요청을 받고 정적 리소스를 제공하는 역할을 합니다. 웹 서버의 대표적 예로는 NGINX와 APACHE 등이 있습니다.
웹 애플리케이션 서버(Web Application Server, WAS)는 앞서 나온 웹 서버의 기능을 대부분 포함합니다. 큰 차이는 프로그램 코드를 실행해서 애플리케이션 로직을 수행할 수 있다는 것입니다.
웹 서버와 마찬가지로 HTTP를 기반으로 동작하며, 정적 리소스 또한 제공할 수 있습니다. 그리고 우리가 짠 프로그램 코드를 실행해서 애플리케이션 로직(요리)을 수행합니다.
WAS는 동적 HTML을 생성할 수 있으며, HTTP API, REST API(JSON) 등을 지원합니다. Servlet, JSP, Spring MVC 같은 것들이 WAS에서 동작합니다.
대표적인 WAS로 톰캣(Tomcat), Jetty, Undertow 등이 있습니다.
둘의 용어와 경계는 사실 모호합니다. 웹 서버도 프로그램을 실행할 수 있고, WAS도 웹 서버의 기능을 제공합니다. 하지만 각각 집중적으로 개발된 목적이 다릅니다. 앞선 예로 설명해보자면 웹 서버는 기본적인 응대와 상품 제공을 할 수 있는 아르바이트생, WAS는 요리까지 할 수 있는 매니저 혹은 사장님이라 생각해도 좋을 것 같습니다.
웹 애플리케이션이라는 시스템을 구성하기 위해서 WAS와 DB만 있다면 필요한 모든 기능을 제공할 수 있습니다. WAS는 정적 리소스와 애플리케이션 로직 모두를 제공할 수 있기 때문입니다. WAS의 애플리케이션 로직에서 DB를 조회해서 필요한 HTML을 동적으로 만들 수 있습니다.
대신 이제 WAS 혼자 이런저런 일을 다하는 안쓰러운 상황이 만들어졌습니다. 이렇게 되었을 때의 문제점이 몇 가지 있습니다.
첫째, 서버 과부하의 우려가 있습니다.
둘째, 비싼 애플리케이션 로직이 정적 리소스 제공 때문에 수행이 어려워질 수 있습니다. HTML, CSS, JS 등의 정적 리소스 제공은 동적 리소스를 지지고 볶고 하는 일보다 훨씬 가벼운 작업입니다. 정적 리소스는 위치를 찾아서 반환하면 그만이지만, 동적 리소스는 데이터베이스에서 데이터를 찾아와 가공하고, 애플리케이션 로직에 따라 엣지 케이스 등을 처리해야되기 때문입니다. 이런 힘든 일을 정적 리소스 서빙 때문에 늦춰지면 전체적인 서비스 운영에 지장이 갑니다.
셋째, WAS 장애시 아무것도 제공할 수가 없습니다. 단일 장애점(Single point of failure)라고도 합니다. WAS는 개발자가 직접 설계 및 구현하기 때문에 버그가 발생할 수 있고 때문에 장애가 나기 쉽습니다. 이때 너무 많은 역할을 가진 WAS의 장애가 서비스 전체의 장애로 전파됩니다. HTML을 반환할 수 없으니, 유저는 오류가 났다는 화면조차 받을 수 없습니다. 사장님이 쓰러졌는데 문 닫는다는 표시를 안 해주면 손님은 계속 들어와서 기다리는 것입니다.
웹 서버가 정적 리소스를 처리하고, 그러다 동적인 로직이 필요한 페이지의 경우 웹 서버가 이를 WAS에게 전달합니다. 그러면 해당 요청을 WAS가 처리해서 웹 서버로 반환, 그걸 다시 웹 서버가 클라이언트에게 서빙합니다.
이렇게 하면 WAS가 서비스에 중요한 애플리케이션 로직을 전담할 수 있다는 장점이 있습니다. 웹 서버와 WAS가 업무를 분담하게 되는 것입니다.
또한 시스템 리소스를 효율적으로 쓸 수 있습니다. 만약 정적 리소스를 많이 필요로 하는 경우, 웹 서버를 요구에 맞춰 증가(확장) 시킬 수 있습니다. 반대로 애플리케이션 리소스가 많이 요구되면 WAS를 증설할 수 있습니다.
그리고 정적 리소스만 제공하는 웹 서버는 잘 죽지 않습니다. 반면 힘든 일을 하는 WAS는 잘 죽습니다.
WAS가 문제가 생길 확률이 높은 만큼 이에 대비하면 좋습니다. 웹 서버와 WAS가 분리되어 있으면 WAS에 문제가 생겼을 때, 클라이언트에게 오류 화면을 제공해줄 수 있습니다.
해당 글에서는 네트워크나 HTTP 등에 대해 자세히 다루지 않았지만, 이러한 부분을 추가적으로 이해하면 웹 서버의 동작을 이해하는데 많은 도움이 됩니다.
🙇 잘못된 정보나 피드백이 있다면 얼마든지 남겨주세요!