HTTP 통신
거의 모든 웹을 통한 데이터 송수신은 HTTP 기반으로 이루어진다. HTML, TEXT와 같은 정적 리소스부터, 이미지나 음성, 영상, 파일, JSON, XML 등 HTTP를 통해 거의 모든 형태의 데이터 전송이 가능하다.
웹 서비스에서는 웹 서버와 웹 어플리케이션 서버가 이러한 HTTP 통신을 통해서 웹 페이지를 클라이언트에 전달한다.
웹 서버(Web Server)
웹 서버는 클라이언트(사용자)가 브러우저 주소창에 url을 입력하여 어떤 페이지를 요청하게 되면, HTTP 요청을 받아 HTML과 같은 정적인 컨텐츠를 사용자에게 제공하는 서버를 말한다. 정적인 컨텐츠란 HTML, CSS, 이미지, 영상, 파일 등 저장되어있는 곳에서 꺼내 즉시 응답 가능한 컨텐츠이다.
웹 서버에서는 정적 컨텐츠는 직접 응답을 보내고, 동적 컨텐츠에 대한 요청을 받으면 WAS에 해당 요청을 넘겨 처리 후 그 응답을 클라이언트에 전달하는 역할도 맡는다.
웹 서버에는 NGINX, APACHE, IIS(Windows 전용 웹서버) 등이 있다.
웹 어플리케이션 서버(WAS, Web Application Server)
WAS는 HTTP 요청을 받아 DB 조회와 다양한 비즈니스 로직을 처리하여 해당 처리 결과를 반영한 동적 컨텐츠를 제공하기 위한 Application 서버를 말한다. 동적 컨텐츠란 동적 HTML이나 HTTP API(JSON, XML)와 같은 요청에 대한 응답 데이터를 담은 컨텐츠를 말한다.
사용자의 컴퓨터나 장치에서 어플리케이션을 수행하는 미들웨어로 주로 데이터베이스 서버와 같이 수행되고, 서블릿과 JSP의 구동환경을 제공하기 때문에 서블릿 컨테이너 혹은 웹 컨테이너로 불리기도 한다.
WAS에는 Tomcat, Jetty, Undertow, JBoss, WebSphere 등이 있다.
웹 서버와 웹 어플리케이션 서버
위의 설명에서도 알 수 있듯, 웹 서버는 주로 정적 컨텐츠를 처리하기 위한 서버이고 WAS는 어플리케이션 로직과 동적 컨텐츠를 처리하기 위한 서버이다.
WAS 자체로도 Web Server와 Web Container(JSP, Servlet을 실행시킬 수 있는 소프트웨어)의 역할을 모두 수행할 수 있다.
하지만 다음의 몇 가지 이유에 의해 두 서버를 분리해 운영하는 것이 좋다.
•
서버 과부하 방지
◦
WAS를 통해 모든 것을 처리하는 어플리케이션에서는 WAS가 너무 많은 역할을 담당하고, 그로 인해 서버의 과부하가 발생할 수 있다.
◦
정적 컨텐츠를 처리하는 Web Server와 동적 컨텐츠와 어플리케이션 로직을 처리하는 WAS를 분리하면 서버의 과부하를 줄일 수 있다.
•
장애 대처
◦
어플리케이션 로직을 수행하는 WAS 특성상 장애가 자주 발생할 수 있는데, 정적 컨텐츠를 수행하는 Web Server는 장애가 거의 발생하지 않는다.
◦
WAS 장애 시 Web Server에서 장애 상황에 대한 HTML을 지정하여, 클라이언트에서 접속이 안될 때 오류 화면으로 장애 상황을 알릴 수 있다.
•
보안
◦
SSL에 대한 암호화, 복호화 처리에 웹 서버를 사용 가능하다.
•
확장성
◦
웹 서버에서 로드 밸런싱을 수행하여, 여러 대의 WAS를 연결해 무중단 운영 및 장애에 쉽게 대응할 수 있다.
◦
성능에 따라 정적 리소스가 많이 사용되는 경우 웹 서버만 증설하거나, 어플리케이션 리소스가 많이 사용되는 경우 WAS만 증설할 수 있다.
WAS와 스레드 풀
WAS에서는 요청이 들어오면 스레드에서 해당 요청을 처리하는데, 요청이 많아지는 경우 스레드를 하나만 사용하면 요청이 지연되고 이전의 요청이 끝날 때까지 대기해야한다.
이를 위해 다중 스레드를 통해 요청을 처리해야하는데, 문제는 요청이 들어올 때마다 스레드를 생성하고 요청이 끝나면 스레드를 종료하는 방식은 비효율적이다. 스레드를 생성하는 비용이 매우 비싸기 때문에, 요청마다 스레드를 생성하면 해당 요청에 대한 응답 속도가 늦어질 수 밖에 없다. 또한 단기간에 요청이 많이 들어와 스레드가 지나치게 많이 생성되면, 메모리에 과부하가 걸린다.
이런 이유들로 WAS에서는 최초 로딩 시 스레드 풀에 특정 수만큼 스레드를 생성해두고, 요청이 들어오면 풀에 있는 스레드를 할당했다가 요청이 끝나면 해당 스레드를 풀로 회수한다.
이를 통해 스레드를 생성하고 종료하는 오버헤드를 절약하여 빠르게 응답 시간을 줄일 수 있다.
만약 스레드 풀에 남은 스레드가 없다면 요청을 일정 시간동안 대기시키거나 거절할 수 있다.
WAS에서 주요 튜닝 포인트는 스레드 풀의 최대 스레드(max thread) 개수이다.
•
최대 스레드 수가 너무 적으면, 동시 요청이 많은 경우 클라이언트에서 응답 지연이 발생할 확률이 높고 CPU의 사용량이 낮게 유지될 수 있다.
•
최대 스레드 수가 너무 많으면, CPU와 메모리 리소스에 많은 부하가 걸릴 수 있고 그로 인해 서버가 다운될 수 있다.
HTTP 응답 형식
정적 리소스는 HTML 파일, CSS, 이미지, 영상 등 저장되어 있는 리소스 파일들을 말한다. HTTP 요청에 응답으로 데이터를 꺼내 제공하기만 하면 되고, 리소스가 변하지 않는 이상 언제나 같은 결과를 받을 수 있기 때문에 정적 리소스라 부른다.
그에 반해 동적 리소스에는 HTML 페이지와 HTTP API가 있다.
•
HTML 페이지
◦
HTML 페이지는 사용자의 요청에 따라 데이터를 처리한 결과를 동적으로 HTML 파일로 생성하여 전달하는 방식을 말한다.
◦
JSP나 타임리프를 통해 HTML 페이지를 동적으로 생성할 수 있다.
◦
이렇게 서버에서 동적으로 HTML을 생성하여 그 결과를 웹 브라우저에 전달하는 것을 서버 사이드 렌더링(SSR, Server Side Rendering)이라 한다.
•
HTTP API
◦
HTTP API는 HTML이 아니라 데이터를 전달하는 것으로, 주로 JSON의 형태로 데이터를 전달하면 클라이언트가 해당 데이터를 가공하여 별도로 처리한다.
◦
클라이언트에서 해당 데이터를 통해 UI를 새로 작성하며, 아이폰이나 안드로이드, PC 앱 같은 앱 클라이언트나 React나 Vue.js 같은 웹 클라이언트에서 사용된다.
◦
이렇게 데이터만 받아 HTML을 클라이언트에서 동적으로 생성하여 적용하는 것을 클라이언트 사이드 렌더링(CSR, Client Side Rendering)이라 한다.