Server가 뭐죠? 서빙하는 사람입니다. 서빙은 뭐죠? 제공입니다. 김밥천국에서 라면을 주문하면 이모님이 라면을 서빙해 주시죠. 네트워크에서의 서버도 동일합니다. 네트워크에서 서버는 사용자에서 정보나 서비스를 제공하는 컴퓨터입니다. 요청에 대한 응답을 하는 시스템이라고 이해할 수 있죠.

서버와 클라이언트는 사실 역할의 개념입니다. 둘 다 컴퓨터라는 점은 동일하고, 단지 서비스를 제공하고 있는 입장이냐 서비스를 받고 있는 입장이냐의 차이만 있을 뿐이죠. 우리도 사람이지만 때로는 콘텐츠를 제공하기도 하고 콘텐츠를 소비하기도 하지 않습니까? 다 똑같습니다.
그렇다면 Web Server는 뭐죠? 웹을 서빙하는 컴퓨터겠네요. 정확히 말하면 웹 구성에 필요한 리소스를 서빙하겠죠.

다시 식당으로 가보죠.
김밥천국에서는 보통 차림표라는 엑셀 표 같은 주문서에 원하는 음식에 대한 수량을 표시하고 이모님에게 전달하는 방식으로 주문이 이루어집니다. 버거킹은 어떤가요? 키오스크에 가서 원하는 햄버거를 선택한 후 무인 방식으로 주문하면 됩니다. 제가 지금 무슨 이야기를 하고 있죠? 식당마다 주문 방법이 다르다는 것입니다.
웹에서도 원하는 정보와 서비스를 얻기 위해 요청과 응답 방식을 미리 약속했는데요 이를 프로토콜이라고 합니다. 구체적으로는 HTTP 프로토콜을 사용하는 것이고요.

웹 리소스에는 HTML 문서, 이미지, CSS 파일 등이 있습니다. 웹 서버는 이러한 웹 리소스만을 응답할 수 있습니다. 래퍼한테 발라드 부르라고 하고, 발라더한테 랩 해보라고 하면 안 되겠죠? 웹 리소스는 정적 콘텐츠와 동적 콘텐츠를 이해하는 것에서 시작됩니다.
웹 리소스는 정적 콘텐츠와 동적 콘텐츠로 구분됩니다.
Static Content, 정적 콘텐츠는 말 그대로 사용자에 따라 변경될 필요가 없는 콘텐츠를 의미합니다.
중앙일보, 조선일보, 한겨레 등 신문은 사용자마다 콘텐츠가 다를 필요가 없죠. 모든 구독자에게 동일한 콘텐츠 내용을 보여줍니다. 회사 소개 랜딩 페이지를 생각해 볼 수 있습니다. 보통 회사를 대표하는 이미지나 그들의 비전을 텍스트로 제시하기 때문에 모든 사용자에게 동일한 콘텐츠를 제공하면 됩니다.
이러한 정적 콘텐츠에는 JPG, GIF, HTML, CSS, JavaScript 등이 있습니다.
별도의 로직이나 데이터베이스가 필요치 않아 구현이 간단하고, 서버에서는 복잡한 처리 없이 단순히 파일을 응답하기만 하면 되므로 응답 속도가 빠르다는 특징이 있습니다.
Dynamic Content, 동적 콘텐츠는 사용자에 따라 변경될 필요가 있는 콘텐츠입니다.
네이버 뉴스 서비스를 생각해 보죠. 네이버 뉴스 팀은 확장성 있는 플랫폼을 만들기 위해 사용자 맞춤형 뉴스를 제공할 수 있습니다. 그리고 실시간 뉴스 업데이트에 대한 고려도 필요하겠죠. 이러한 경우에는 사용자마다 서로 다른 콘텐츠를 동적으로 제공해야 할 필요가 있습니다.
즉, 서버에 저장된 HTML 파일이 있는 그대로 제공되는 것이 아니라 동적으로 만들어지는 콘텐츠가 동적 콘텐츠입니다. 사용자와의 상호작용, 사용자 로그인과 같은 이벤트에 의해 동적으로 콘텐츠가 생성되어야 할 것입니다.
동적 콘텐츠에는 사용자 맞춤형 피드, 실시간 날씨 정보, 추천 상품 등이 있겠네요.

그런데 사용자로서 생각해 보면 요즘 정적 콘텐츠를 소비할 일이 많이 있나요? 개발자로서 생각해 봐도 정적 콘텐츠를 제공할 일은 그리 많지 않은 것 같습니다. 그러면 현대의 웹은 동적 콘텐츠를 어떻게 처리할지를 염두에 둘 수밖에 없겠네요.
다시 웹 서버로 돌아가 보죠. 웹 서버는 웹 리소스를 제공하는 컴퓨터입니다. 웹 리소스는 정적 콘텐츠와 동적 콘텐츠로 구분됩니다. 웹 서버는 어찌 됐건, 정적 콘텐츠와 동적 콘텐츠 모두에 대한 요청을 받고 응답을 제공할 수 있어야 합니다.
그런데 웹 서버는 수학적으로 비유하자면, 정적 콘텐츠와 동적 콘텐츠 요청을 모두 인풋으로 받지만 정적 콘텐츠 응답이라는 아웃풋만을 반환하는 함수입니다. 현대 웹의 핵심은 동적 콘텐츠인데 그러면 동적 콘텐츠는 누가 어떻게 처리한다는 얘기죠? 누가에 대한 답은 할 수 있겠네요. WAS입니다.
Web Application Server(이하 WAS)는 사용자가 요청한 동적 콘텐츠를 생성하고 응답하는 역할을 수행하는 소프트웨어입니다. 데이터베이스 연동을 통해 애플리케이션의 핵심 비즈니스 로직을 수행하게 됩니다.
WAS는 웹 서버와 동일하게 HTTP 프로토콜을 기반으로 동작합니다. 즉, 웹 서버로부터 넘어온 HTTP 요청을 처리할 수 있습니다. 이때 요청을 처리하고 응답해 줄 내용을 생성해야 하는데, 이 작업을 수행하는 것이 Servlet입니다.

Servlet은 Java 웹 애플리케이션 개발 환경에서 사용자의 요청을 받아 처리하고 HTML, JSON과 같은 형식으로 데이터를 구성한 뒤 동적 페이지로 만들어서 응답을 반환하는 일종의 모듈입니다. 이러한 Servlet을 생성하고 관리하는 영역을 Servlet Container라고 합니다.
그런데 사실 WAS는 웹 서버와 Servlet Container가 결합된 형태를 의미합니다. Servlet Container를 Web Container라고 부르기도 합니다. 대부분의 WAS는 웹 서버의 역할도 수행할 수 있다는 점을 의미합니다. 대표적으로 Tomcat이 있는데 Spring Boot에는 Tomcat이 내장되어 있다고 합니다. 이 부분은 Java를 다룰 날이 오게 된다면 공부해 보겠습니다.

그런데 저는 프로젝트에 뭣도 모르고 Nginx라는 웹 서버를 연결했습니다. 당시에는 리버스 프록시 기능이 필요해서 사용했습니다. Nginx 전에는 Apache가 있었습니다.
각각에 대해 학습하는 것은 차치하더라도, 문득 이런 생각이 듭니다. WAS도 웹 서버의 기능을 수행할 수 있는데 굳이 왜 Apache나 Nginx와 같은 웹 서버를 별도로 사용해야 할까? 알바생 한 명 뽑아서 홀도 맡기고 주방도 맡기면 되는데, 왜 주방 알바를 따로 뽑으려고 하냐 이 말입니다. 벌써 느낌 오죠?
핵심은 목적에 따른 역할 분리에 있습니다.
테이블 10개 정도 되는 식당이라면 알바생 혼자 주방 일을 도우며 요리도 하고, 완성된 요리를 서빙도 할 수 있습니다. 그런데 알바생을 싼 맛에 굴리다가 부담에 못 이겨 관둔다고 하면요? 이거야말로 컴퓨터쟁이들이 가장 싫어하는 single point of failure 상황 아닙니까? 그리고 사업이 잘 돼서 테이블 100개 규모의 사업장이 되면요? 그때도 그 알바생 한 명에게 모든 업무를 기대하며 채찍질할 건가요?

역할 분리에 따른 장점에는 다섯 가지가 있습니다.
WAS 오류 대처
알바생에게는 홀 서빙 업무만 주자는 것입니다. 그리고 WAS는 요리만 담당하는 것이죠. 주방에서 주문이 엉켜 문제가 생겨도 최소한 알바생은 테이블에 앉아 있는 손님들에게 양해를 구할 수 있는 여력이 생기겠죠. 웹 서버로 보면 최소한 오류 안내 페이지는 노출할 수 있다는 것입니다.
로드 밸런싱
주방 업무가 계속 밀려 주방 알바생을 두 명 더 채용해 총 세 명이 주방에서 근무하고 있습니다. 홀 알바생이 주방의 모습을 보고, 현재 바쁘지 않은 다른 주방 알바생에게 지금 들어온 주문을 처리해 줄 것을 요청할 수 있죠. 이처럼 요청을 여러 WAS에 분산시켜 서버 부하를 방지할 수 있고, 이를 컴퓨터쟁이들은 멋있게 로드 밸런싱이라고 표현합니다.
헬스 체크
WAS의 상태, 즉 주방 알바생들의 상태도 체크할 수 있습니다. 일을 한 지 얼마 안 돼서 너무 힘들어하는 주방 알바생이 있을 수 있죠. 다 사람이 하는 일이니까요. 이럴 때에는 해당 WAS를 로드 밸런싱 대상에서 제외할 수 있습니다. 잠깐 나가서 커피 한 잔 마시라고 한 뒤에 다시 로드 밸런싱 대상에 포함하는 유연함을 발휘할 수 있죠.
보안
그리고 Apache나 Nginx와 같은 웹 서버를 앞단에 두고 사용하는 것 자체로도 보안 측면에서 유리합니다. 홀 알바생이 혼자서 주방에 들락날락할 때에는 냉장고의 위치가 드러납니다. 좀 유치하긴 하지만 엄청 나쁜 손님이 고기가 있는 냉장고 위치를 파악한 뒤 알바생이 바쁜 틈을 타 고기를 훔칠 수도 있겠죠. 말이 그렇다는 겁니다. 웹 서버를 앞단에 두면 WAS의 IP 주소는 노출되지 않습니다. 웹 서버의 프록시 설정을 통해 WAS의 응답 헤더에서 불필요하거나 민감한 정보를 제거하거나 클라이언트의 요청 URL을 다른 URL로 변경하는 등의 추가적인 보안 조치도 가능하겠죠.
캐싱
캐싱 기능도 있겠습니다. 손님들이 소주나 맥주처럼 자주 주문하는 품목은 술 냉장고에 캐싱 해두어, 주방까지 가지 않고 홀 알바생, 즉 웹 서버가 처리할 수 있습니다.
Nginx에 대해 설명하는 글을 작성하려고 했습니다. 그리고 필연적으로 Nginx 이야기는 데이터베이스로 이어질 수밖에 없어서 AWS RDS에 대해서도 논하려 했습니다. 그런데 Niginx는 웹 서버고, 웹 서버는 WAS의 구성요소이기도 합니다. 웹 서버 이전에 서버가 있기도 하고요.
본질에 대해서 고등학생 수준 정도 되는 친구들에게 설명해서 이해시킬 자신이 없다면, 나머지 작업이 무슨 의미가 있을까 하는 생각이 들어 오늘 글을 작성하게 되었습니다. 백날 천날 남의 말 옮겨봐야, 그런 콘텐츠는 '진심'이 될 수 없다고 생각합니다. 고유함은 나의 주장이고 그 시간이 쌓여서 타인으로부터 얻게 되는 훈장이 진정성인데, 고유함부터 무너지면 사실 나머지는 시간 낭비죠. 다음에는 기존에 계획했던 Nginx에 deep dive 해보겠습니다.