CGI와 Servlet에 대해 이야기하기 전에 먼저 WS와 WAS의 차이에 대해서 이야기하도록 하겠습니다.
일반적으로 웹서버라고 하면 WS와 WAS를 모두 통칭하는 경우가 많지만 이 글에서는 정적인 웹 페이지만을 반환하는 WS와 동적인 요청또한 처리할 수 있는 WAS를 분리해서 설명하도록 하겠습니다.
Web Server (WS)
WS의 정의는 다음과 같습니다.
웹 브라우저와 같은 클라이언트로부터 HTTP 요청을 받아들이고, HTML 문서와 같은 웹 페이지를 반환하는 컴퓨터 프로그램
또는 위에 언급한 기능을 제공하는 컴퓨터 프로그램을 실행하는 컴퓨터
즉 웹서버란 HTTP 프로토콜에 따른 요청을 받아서 HTML과 같은 정적인 웹 페이지를 반환하는 프로그램이나 컴퓨터를 의미한다고 이해할 수 있습니다.
결론적으로 웹서버는 클라이언트의 요청을 받아서 요청에 따른 웹 페이지를 반환해주는 것이 주 목적인 프로그램입니다.
하지만 WS는 단순히 서버에 저장된 웹 페이지를 클라이언트에 요청에 맞춰서 찾아서 반환해줄 뿐이므로
클라이언트의 데이터베이스에 정보를 저장하려하는 행동과 같은 동적인 요청에 대해서는 처리를 해줄 수 없습니다.
이런 배경에서 동적인 요청을 처리할 수 있게 만들어진 것이 Web Application Server (WAS) 입니다.
Web Application Server (WAS)
WAS의 정의는 다음과 같습니다.
인터넷 상에서 HTTP를 통해 사용자 컴퓨터나 장치에 애플리케이션을 수행해주는 미들웨어(소프트웨어 엔진)
WAS는 WS와 동적인 요청을 처리하는 애플리케이션의 사이에 있는 미들웨어 를 의미합니다.
WAS는 CGI와 Servlet과 같이 동적인 요청을 처리해주는 애플리케이션에 접근 가능하게 약속된 인터페이스를 구현해서 동적인 요청을 처리해줄 수 있습니다.
CGI와 Servlet과 같은 인터페이스를 통해 DB에 접근이 가능하고, 여러 비즈니스 로직을 처리해서 웹 페이지를 동적으로 생성할 수 있습니다.
그렇다면 CGI와 Servlet은 무엇일까요?
Common Gateway Interface (CGI)
CGI의 정의는 다음과 같습니다.
공용 게이트웨이 인터페이스(CGI)는 웹서버와 외부 프로그램 사이에서 정보를 주고받는 방법이나 규약들을 말한다.
즉, 웹서버가 동적인 요청을 처리하기 위해서 그 요청을 처리하기에 적합한 외부의 애플리케이션을 호출하고, 그 결과를 받아와야할 필요가 생겼기 때문에, 이를 미리 약속한 방법이 CGI입니다.
이 CGI 프로토콜을 지켜서 애플리케이션을 만든다면, 동적 웹서버에서 실행 가능한 애플리케이션이 되는 것입니다.
그런데 CGI는 여러가지 성능에 대한 단점이 있었습니다.
그 중, 치명적인 단점은 CGI는 각각의 Request에 대해서 새로운 프로세스를 생성해서 처리한다는 것입니다. (즉, 쓰레드를 만드는 것이 아닌 fork를 하는 방식입니다.)
이 때문에 Java 진영에서는 Servlet이라는 새로운 CGI가 등장하게 됐습니다.
Servlet
Servlet의 정의는 다음과 같습니다.
클라이언트의 요청을 처리하고, 그 결과를 반환하는 Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍 기술
즉, Servlet은 자바로 구현된 CGI라고 이해할 수 있습니다.
Servlet이 CGI보다 개선된 사항중 하나는 CGI의 치명적인 단점이었던 Request별로 새로운 프로세스를 생성하던 것이 Request별로 새로운 Thread를 생성하는 것으로 바뀌었다는 것입니다.
이를 통해서 더 적은 비용으로 동적인 요청을 처리할 수 있습니다.
이 서블릿을 사용하기 위해서 요청에 따라 적절히 서블릿을 생성하고 관리하는 서블릿 컨테이너가 필요합니다.
Servlet Container
서블릿 컨테이너는 서블릿 관리를 처리하는 WAS의 일부 기능을 담당합니다. (즉, WAS가 서블릿 컨테이너를 포함합니다.)
서블릿 컨테이너는 웹 컨테이너의 일종이기 때문에 웹 컨테이너의 정의를 살펴보면 다음과 같습니다.
웹 컨테이너(web container, 또는 서블릿 컨테이너)는 웹 서버의 컴포넌트 중 하나로 자바 서블릿과 상호작용한다. 웹 컨테이너는 서블릿의 생명주기를 관리하고, URL과 특정 서블릿을 맵핑하며 URL 요청이 올바른 접근 권한을 갖도록 보장한다.
서블릿은 객체로 사용되기에 이를 생성하고, 처리하고, 소멸하는 등의 생명주기를 처리하고 작업을 수행하는 무언가가 필요합니다. 이 역할을 해주는 것이 서블릿 컨테이너입니다.
또한 서블릿 컨테이너는 쓰레드에 대해서도 관리를 해주는 역할을 합니다.
쓰레드를 생성하고 소멸하는데 많은 비용이 들기 때문에 미리 만들어둔 쓰레드를 재사용하기 위한 쓰레드 풀을 관리하는 등의 작업을 수행해줍니다.
이러한 서블릿 컨테이너는 웹서버와 WAS의 소켓을 이용한 통신을 처리하고, 이를 통해 애플리케이션 개발자가 서버와의 통신에 대해 여러 복잡한 작업 없이 요청을 주고 받는 등의 처리를 할 수 있습니다.