What is the difference between Servlet and Servlet container? 서블릿과 서블릿 컨테이너의 차이점은 무엇인가?(각각의 역할에 대하여)
얼마 전에 친구와 대화하다가 나온 이야기입니다....

출처: 구글
친구: '너... Servelt이 뭔지 정확히 알고 있어?'
본인: '아니... 그거 JSP 사용할 때... Html을 동적으로 처리해 줄 때 쓰는 거 아니야?'
말하고 나서 골똘히 생각해 보니, JSP와 Servlet 과의 차이점이 뭔지도 모르고 어떤 게 상위 개념인지도 모르겠는 겁니다.... 한번 더 골똘히 생각해 보니, 저는 서블릿(Servlet)으로도, JSP로도 개발을 한 적이 없고, Client 단 개발을 할 때는 오로지 분리된 Client 단만을 개발해왔으며(이 Client 단은 전부 Html, Css, Javascript로 구성이 되어있죠 프레임 워크는 VUE나 REACT로 구성되어 있었고요), API 서버 또한 오로지 요청을 받고 응답만으로 데이터를 내려주는 API 서버만을 접해왔기 때문에 Servlet이라는 단어에 대해서 깊게 생각해 볼 기회가 적었습니다.
JSP <-> 서블릿(Servlet) <-> 서블릿 컨테이너(Servlet Container) <-> Web Server ...?
그래서 생각난 김에 서블릿(Servlet)이 뭔지 서블릿 컨테이너(Servelt Container)가 뭔지 정확하게 짚고 넘어가야겠다는 생각이 듭니다. 서블릿 컨테이너(Servlet Container)와 웹서버와의 차이점은 무엇일까요?? 추가로 서블릿(Servlet)과 JSP와의 차이점도 간단하게 다루어보겠습니다.

출처: 구글
현시점에서 서블릿(Servelt)이나 JSP로 개발할 일은 많지 않겠지만 여전히 많은 서적, 특히 Spring 관련 서적에서 예제로 JSP와 Spring을 함께 다루고 있고 이때 꼭 빠지지 않고 등장하는 개념이 서블릿(Servlet)이기 때문입니다.
서블릿(Servelt)은 클라이언트의 요청을 처리하고, 그 결과를 다른 클라이언트에게 전송하는 Servlet Class의 구현 규칙을 지킨 Java program입니다. 즉 JVM 기반에서 웹 개발을 하기 위한 명세이자 API입니다.
Java enterprise edition(Java EE라고 줄여서 많이 이야기하곤 합니다)에 포함된 스펙 중에 하나로, Java에서 http 요청과 응답을 처리하기 위한 내용을 담고 있습니다.
Java를 Web에서 조금 더 쉽게 활용하기 위하여 만든 API 들이며 규약에 맞게 클래스나 라이브러리들을 상속하여 만든 클래스들을 서블릿(Servelt)이라고 합니다.
목차
1. 서블릿(Servlet)
2. 서블릿 컨테이너(서블릿이 돌아가는 환경)
3. 서블릿 컨테이너와 웹서버와의 차이점
4. 서블릿과 JSP와의 차이점
1. 서블릿(Servlet)이 어떤 놈인지는 알겠어요, 그렇다면.... 이 아이는 어떻게 어디에서 동작하나요?

(서블릿의 동작 과정과 메모리 적재에 대해서도 자세하게 다루고 싶었지만 저의 현재 수준이 그 정도가 되지가 못해서 다른 분의 포스팅으로 위임하겠습니다. 위 포스팅을 작성해 준 개발자님께 감사드리며 문제시 댓글 남겨주시면 삭제하겠습니다)
서블릿은 자신만의 생명주기를 가지고 있습니다(서블릿이 자신의 생명주기를 스스로 관리한다는 이야기는 아닙니다) 서블릿은 개발자가 소스를 작성한 후 컴파일 과정을 거쳐 컨테이너에 배치(deploy) 하게 되면 서블릿 컨테이너에 의해 실행됩니다. 조금 더 자세하게 알아보면 ....
(1) 사용자의 요청에 따라 스레드 단위로 실행되면서 비즈니스 로직 및 데이터 베이스 연동 등 작업을 수행하고 처리 결과를 사용자에게 HTML 형식으로 전달하는 구조로 동작합니다.
(2) 서버에서 서블릿 컨테이너에 의해 실행되고 생명주기를 가지며 특정 이벤트와 상태가 존재하는 구조입니다.
(서블릿 컨테이너에서 서블릿 클래스를 로딩합니다)
(3) 서블릿 개발은 해당 생명주기 메서드를 오버라이딩하거나 doGet(), doPost()와 같은 사용자 요청 처리 메서드를 구현합니다.
(4) init()은 서블릿 실행 시 한 번만 실행되는 메서드이고(위의 포스팅을 참고하시면 조금 더 자세히 살펴보실 수 있습니다), service() 메서드는 사용자 요청 시 매번 호출되는 메서드입니다. destory()는 서블릿 종료 시 실행되는 메서드입니다.
(서블릿 객체가 생성되면, 서블릿 객체에서 init()을 호출합니다. init()은 초기화 작업을 수행합니다.)
(5) 그 후 스레드에서는 사용자 요청을 처리합니다. 계속해서 사용자의 요청에 따라 service() 메서드가 반복 호출되며 사용자가 원하는 처리를 합니다.
(6) 생명주기에 대해서 조금 더 자세하게 설명드리면, 웹 어플리케이션 컨테이너에서 context가 초기화되면 생명주기가 시작됩니다. 서블릿의 생명주기는 초기화, 서비스, 소멸의 3단계로 구성되어 있습니다.
초기화 단계에서는 로드한 서블릿의 인스턴스를 생성하고 리소스를 로드하는 등 클래스 생성자의 초기화 작업과 동일한 역할을 수행합니다. 서비스 단계에서는 클라이언트의 요청에 따라서 호출할 메서드를 결정합니다.
소멸단계에서는 서블릿이 unload 됩니다. unload는 런타임 오류가 발생하거나 서블릿 컨테이너가 종료되었을 때 발생하는데 이때 서블릿이 unload 되어 서블릿의 메서드 호출 결과가 정상적으로 표출되지 않습니다.
(7) 서블릿에서는 doGet 메서드를 이용해서 GET 메서드 방식의 요청을 받을 수 있습니다.
doGet은 HttpservletRequest와 HttpServeltResponse를 파라미터로 전달받도록 되어있는데, 이름에서 유추할 수 있듯이 HttpServletRequest는 요청에 대한 정보를 가지고 있고, HttpServeltResponse는 브라우저에서 정보를 표현하기 위해 사용됩니다.
2. 그래요? 그렇다면, 서블릿은 어떠한 환경에서 돌아갈까요?
위에서 잠깐 언급했는데요....
Java를 실행하려면 JRE(Java runtime environment)가 필요하듯... 서블릿을 실행하려면 서블릿 컨테이너가 필요합니다. 서블릿이 서블릿 컨테이너(Servlet Container)에서 어떻게 동작하는지, 그림으로 조금 더 자세히 알아보면 아래와 같습니다.

(올려주신 개발자님 감사합니다 그림이 너무 좋아서 첨부했는데 문제 되면 지우겠습니다)
위처럼 서블릿 컨테이너는 HttpRequest를 가로채서 Servlet Container으로 넘깁니다. 그리고 Servlet Container는 Servlet으로 요청을 넘겨서 서블릿의 생명주기를 관리하며, 요청 요청마다 스레드를 새로 생성합니다.(반복해서 말씀드려서 죄송합니다 저는 이 부분이 중요하다고 생각해서 반복적으로 언급하게 되네요. 개인적으로 가장 궁금했던 부분이었습니다.)
3. 서블릿 컨테이너가 뭐 하는 놈인지는 알겠어요... 그렇다면... 현업에서는 웹서버라는 단어도 많이 사용하던데, 웹서버라는 것과는 어떠한 차이점이 있나요?
서블릿 컨테이너는 서블릿을 실행하기 위한 서버 소프트웨어를 말하는 것으로 JSP 나 서블릿으로 만들어진 웹 프로그램을 개발하고 실행하기 위한 환경입니다. 대표적으로 톰켓이 있습니다.
하지만 웹서버 == 톰켓이 아니잖아요?
그렇다면 (쉽게 말해서) 웹서버와 톰켓의 차이점은 무엇인지 알아보겠습니다!
웹서버와 서블릿 컨테이너의 차이점
(1) 웹서버는 '웹서비스'를 제공하기 위해 필요한 서버 기반의 소프트웨어입니다.
서블릿 컨테이너는 서블릿으로 개발된 자바 프로그램을 실행하고 처리하기 위한 서버 기반의 소프트 웨어입니다.
(2) 웹서버가 처리하는 컨텐츠는 Html, Css, Javascript 등의 asset 파일들입니다.
서블릿 컨테이너가 처리하는 컨텐츠는 서블릿 클래스입니다.
(3) 웹서버는 컨텐츠가 위치한 URL 요청에 의해 실행되어 요청할 때마다 매번 디스크에서 읽어서 처리합니다.
서블릿 컨테이너는 서블릿 클래스 정보에 따라 매핑된 URL 정보에 따라 실행하며 컨테이너에 적재된 상태에서 처리합니다.(이 때문에 매번 init()이 호출되지 않죠 위에서 언급 드린 것처럼요)
(4) 웹서버는 웹서버 자체로 JSP를 읽어들이거나 처리할 수 없습니다. 웹서버가 서블릿 컨테이너로 처리를 넘깁니다. 서블릿 컨테이너는 JSP를 자체로 처리할 수 있습니다.
(5) 웹서버는 서비스 제공을 위한 다양한 설정을 제공합니다. 서버를 유연하게 운영하려면 웹 서버를 운영해야 합니다. 서블릿 컨테이너는 컨테이너에 따라 기본적인 웹 서버 기능을 내장하고 있으나 고급 설정이나 성능이 떨어지기 때문에 웹서버와 병행해서 사용하는 것이 좋습니다.
위를 요약하면 우리가 이때까지 살펴본 요청에 대한 처리는....
Client가 무언가를 요청
-> 웹서버가 받아서, 서블릿 컨테이너로 넘김
-> 서블릿 컨테이너는 서블릿으로 넘김
-> 서블릿은 init() 되고, 요청이 들어온 것에 대한 처리를 함
이렇게 되는 것이죠.....
휴..... 사용자의 한 가지 요청으로도 이렇게 많은 처리를 하는 줄 오늘 알았네요. 하지만 계속 궁금해하던걸 조금은 해소하게 된 것 같아서 기분이 좋습니다.
(웹서버에서 처리할 수 있는 처리는 웹서버에서, 서블릿 컨테이너에서 처리할 수 있는 처리는 서블릿 컨테이너에서 처리하면 될 것 같아요)
4. 그렇다면, 다시 초심으로 돌아와서 서블릿과 JSP 각자의 차이점은 어떻게 되는데요??
이 두 가지 용어에 대한 차이가 궁금해요.
Spring을 공부하시는 분이라면 JSP로 웹페이지를 많이 만들어보셨을 것 같은데요.
JSP는 서블릿 기반의 웹 프로그래밍 기술로 내부적으로 JSP는 서블릿으로 변환되어 실행됩니다.
즉, 별개의 개념이 아니라 JSP보다 Servlet이 더 상위의 개념이고, JSP의 동작 방식은 내부적으로 Servlet의 동작 방식과 같다는 것이죠...
서블릿이나 JSP나 만드는 방식에 차이가 있을 뿐, 동일한 역할을 합니다. 즉!! 본질적으로 기능의 차이는 없고 역할만 다릅니다. 초기에 자바 Web 개발은 Servlet을 이용한 웹 개발뿐이었고, 차후에는 JSP라는 기술이 등장하면서 JSP 형태의 개발이 유행하게 되고 지금에 와서는 두 개가 각각 역할을 나누어서 개발을 하고 있습니다.
하지만 모든 기업에서 역할을 분리해서 개발하고 있는 것은 아니라고 생각합니다.
어떤 곳에 가면
Client <-> JSP(View+Controller) <-> Model <-> Database
이렇게만 구성되어 있는 곳도 있고,
Client <-> JSP(View) <-> 서블릿(Controller) <-> Model <-> Database
위와 같이 구성되어 있는 곳도 있습니다.
저는... 분리하는 걸 워낙 좋아해서 아주아주 개인적으로는 후자를 선호하는 편입니다.
그럼 본격적으로 둘의 차이를 알아보겠습니다.
서블릿과 JSP와의 차이점
1. 서블릿은 Java 코드 안에 Html을 작성하는 형태로 개발을 하고, JSP는 Html 안에 Java 코드를 작성하는 형태로 개발합니다.
(개인적으로, Java 코드 안에 Html을 작성하게 되면 나중에 누군가가 유지 보수하거나 읽기에 정말 힘들 것 같습니다. 간단하게는 몰라도 아주 길게 Java Code 안에 Html 코드가 들어간다고 하면.... 저는 정말 읽기 힘들 것 같습니다....)
2. 서블릿이 수정된 경우 Java Code를 컴파일 한 후 동적인 페이지를 처리하기 때문에 전체 코드를 다시 업데이트하고 다시 컴파일 한 후에 재배포 하는 작업이 필요합니다.
JSP가 수정된 경우에는 재배포할 필요 없이 WAS가 알아서 처리합니다.
3. 서블릿의 경우 주로 화면과 통신하여 자료를 받아 Service 단을 호출하는 Controller의 역할을 담당합니다.
JSP의 경우 어떠한 로직을 처리하기 위한 코드를 기재하지 않고 보여주기 위한 화면만을 코드로만 이루어져 있습니다.(request 객체나 session 객체에 저장된 정보를 토대로 화면 출력)
정리하자면 JSP는 서블릿의 개조 버전이라고 할 수 있겠습니다.
JSP를 이해하려면 서블릿을 위한 이해가 필수라고 생각됩니다.
그렇다면 요세 JSP로 개발안하던데 서블릿은 현재 아예 쓰이지 않는 개념이냐?
아닙니다. 서블릿으로 부터 http요청의 헤더에서 토큰값을 꺼내서 사용한다던지
Session에 관한 처리를 한다던지 하는 처리를 하면 됩니다.
결론은 현대의 웹 씬에서는 JSP에 해당하는 부분만
Html Css Javascript (Angular or Vue or React)로 바뀐 것이고
서블릿의 역할은 과거와 다르게 Controller의 역할만을 담당하고 있습니다.
아래 블로그에서 이해에 정말 많은 도움을 받아서 아래 블로그 글 또한 링크 달아둡니다.
긴 글 읽어주셔서 감사합니다.
오랫동안 헷갈렸던 지식인데 글을 쓰면서 정리된 것 같아서 기분이 좋네요 ㅎㅎ