클라이언트와 서버의 통신은 HTTP를 기반으로 통신을 한다.
HTTP 프로토콜을 통해 데이터를 주고 받을 수 있고 정적 파일을 제공해준다.
간단히 요약하면 웹 서버는 정적 리소스, WAS는 애플리케이션 로직을 실행하는 서버이다.
그러나, WAS가 웹 서버의 역할을 제공할 수 있고, 웹 서버 또한 프로그램을 실행하는 기능을 포함하기도 한다.
이렇듯, 둘의 용어와 경계가 모호한데 간단히 이렇게 생각하자.
얼핏 봤을 때 WAS는 웹 서버 + 부가적인 기능이니깐 WAS와 DB만 이용해서 충분히 시스템을 구성할 수 있겠다라는 생각이 들것이다.
이게 가능할까? 가능은 하지만 다음과 같은 문제점이 있다.
그래서 보통 시스템을 구성할 때는 WAS와 웹서버 2개를 사용한다. 다음 그림을 보자.
WAS는 중요한 애플리케이션 로직 처리에만 전담할 수 있고, 웹 서버는 간단한 정적 리소스만 전담할 수 있어 시스템 리소스를 효율적으로 사용할 수 있다.
또한, 정적 리소스가 많이 사용되면 웹 서버만 증설, 애플리케이션 리소스가 많아지면 WAS를 증설하면 된다.
마지막 문제점 중 하나인 WAS나 DB 장애시 웹 서버를 통해 오류 화면 제공이 가능하다. (참고로, 웹 서버는 WAS나 DB에 비해 거의 장애가 나지 않는다. 이 둘은 장애가 생각보다 자주 발생)
서버가 클라이언트의 다음과 같은 요청 메시지를 읽고 응답을 하는 경우를 생각해보자. 서버에서 처리해야하는 업무는 다음과 같다.
개발자는 비즈니스 로직 실행만 집중하면 된다. 그러나 이외에 수행 단계가 너무 많다.
서블릿은 이러한 과정 중 방금 언급한 비즈니스 로직 실행 단계를 제외한 모든 일을 대신 해줌으로써 개발자가 비즈니스 로직 실행에만 집중할 수 있도록 해준다.
이를 사용하는 방법을 알아보자. 다음은 서블릿 코드 이다.
@WebServlet(name = "helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) {
// 애플리케이션 로직 작성
}
}
이를 통해 개발자는 HTTP 스펙을 매우 편리하게 사용한다. 서블릿 코드가 실행되면 다음 과정을 거쳐 HTTP 응답 메시지가 클라이언트에 리턴된다.
서블릿 컨테이너는 톰켓처럼 서블릿을 지원하는 WAS를 말한다.
하나의 애플리케이션 코드를 순차적으로 실행하는 것은 스레드이다. 이러한 스레드가 없으면 자바 애플리케이션은 실행이 불가능하다.
스레드는 한 번에 하나의 코드 라인만 수행하므로 동시 처리가 필요하면 스레드를 추가로 생성해야 한다.
단일 요청의 경우 스레드를 하나만 사용해도 상관없다. 그러나, 다중 요청인 경우엔 어떨까?
스레드가 2개의 요청이 오면 병렬적으로 처리를 한다. 이 때 처음 요청에서 오류가 발생한다면 두 번째 클라이언트의 요청이 지연된다.
이를 어떻게 해결할까? 요청마다 스레드를 생성하면 된다. 그러나, 요청마다 스레드를 생성을 하면 이러한 문제점을 해결할 수 있는 것 외 여러 가지 장점이 존재하지만 많은 단점도 존재한다. 자세히 알아보자.
장점
단점
스레드의 생성 비용은 매우 비싸다.
(또한, 고객의 요청 마다 스레드를 생성하면, 응답 속도가 늦어진다.)
스레드는 컨텍스트 스위칭 비용이 발생한다.
컨텍스트 스위칭 : 코어에서 스레드를 다른 스레드로 전환하는 것
예를 들어 스레드 하나가 작업 1~5를 1, 2, 3, 4, 5 순으로 반복적으로 실행하면 작업 1을 실행하고 2, 3, 4, 5를 기다리고 다시 작업 1을 수행하는데 이를 컨텍스트 스위칭이라 한다.
스레드 생성에 제한이 없다.
(이게 왜 단점일까? 잘 생각해보면 고객 요청이 너무 많으면 CPU, 메모리 임계점을 넘어서 서버가 다운될 수 있다.)
이를 보완한 것이 스레드 풀이다.
고객의 요청이 들어오기 전 미리 작업 스레드를 만들어놓고 작업 큐에 요청이 들어오면 스레드들이 순차적으로 작업을 처리한다.
스레드 풀에서 생성 가능한 스레드의 최대치를 관리하고, 요청이 너무 많아 스레드가 부족한 경우 대기/거절이 가능하여 서버가 다운될 우려가 줄어들다.
시작 전 필요한 스레드 만큼을 미리 만들고 사용을 종료하면 스레드 풀에 해당 스레드를 반납하므로 스레드를 생성하고 종료하는 비용이 절약되며 응답 시간이 빠르다.
이러한 스레드 풀에서 중요한 것은 무엇일까? 바로 최대 스레드 수 이다.
이 값을 너무 작게 설정 한 경우
이 값을 너무 크게 설정 한 경우
이렇듯, 최대 스레드 수를 잘 잡는 것이 매우 중요하다. 이 숫자는 바로 알 수는 없고, 성능 테스트를 여러 번 해서 대략적으로 감을 잡아야 한다.
.
.
.
.
핵심은 WAS는 멀티 스레드를 지원해준다. 이는 WAS의 가장 강력한 장점이다.
우리는 싱글 스레드 프로그래밍을 작성하듯 비즈니스 로직만 잘 작성하면 된다.
(최대 스레드 수 같은 것만 개발자가 상황에 맞게 세팅해주면 된다.)
물론 WAS는 멀티 스레드 환경이므로 싱글톤 객체를 다룰 때 주의하자.
고정된 HTML 파일, CSS, JS, 이미지, 영상 등... 이미 생성된 파일을 제공한다.
WAS는 필요한 데이터를 DB에서 조회한 후 얻은 데이터를 동적으로 HTML을 생성한다. 웹 브라우저는 WAS가 생성한 HTML을 해석한다.
데이터 자체를 그대로 전달하는 방식이다. 주로 JSON 형식을 사용한다.
데이터만 주고 받으며 별도의 UI 화면이 필요하면 클라이언트가 별도로 처리한다.
(HTML을 서로 보여주는 전송 방식을 제외한 모든 곳에서 실제 데이터를 주고 받고 실제 프로세스를 호출할 때 모두 사용이 되는 방식)
별도의 html이 없으므로 서버끼리 통신할 때 사용된다.
.
.
.
.
백엔드 개발자가 서비스를 제공할 때 고민해야 되는 포인트는 3가지다.
서버에서 최종 HTML을 생성해서 클라이언트에게 전달하는 방식이다. 웹 브라우저는 단순히 생성된 HTML을 렌더링만 하면 된다.
중요한 것은 백엔드 개발자는 SSR은 필수적으로 알아둬야 한다.
최종 HTML을 자바스크립트를 사용해 웹 브라우저에서 동적으로 생성해서 적용한다.
구글 지도나 메일 새로고침 처럼 동적인 화면에서 주로 사용된다.
(지도를 생각해보자. 확대하거나 축소할 때 화면 깜빡임(새로고침)이 안일어난다.)
웹 프론트엔드 개발자의 전문 분야이다. 하지만 백엔드 개발자도 알아두면 좋다.