이번에 활동하고 있는 교내 개발 커뮤니티에서 WAS, WS, servlet에 대해 Tech talk을 하기로 해서, 어렴풋이 알고있던 개념을 다시한번 공부하게 되었습니다.
백엔드를 하다보면 자주 들었을지도 모르지만, 자세히 공부했던 부분은 아니어서 이번 기회에 새롭게 정리한다는 생각으로 여러 곳의 자료를 찾아보고 정리했습니다.
먼저 WS, WAS를 간단하게 정의하면 다음과 같습니다.
WS: web server로 정적인 컨텐츠를 제공 할 수 있다.
WAS: web application server로 동적인 컨텐츠를 제공 할 수 있다.
그럼 왜 WS는 정적인 컨텐츠를 제공하고, WAS는 동적인 컨텐츠를 제공 할 수 있을까요?
WAS에서 WS의 기능을 수행 할 수 없을까요?
물론, WAS는 WS의 기능을 수행 할 수 있습니다
그럼 왜 이렇게 기준을 나누고 정의하는지 좀 더 찾아보았습니다.
WS는 위에서 말했던 것처럼 단순히 정적인 컨텐츠를 제공합니다.
WS가 정적인 컨텐츠를 제공하는 방법은 다음과 같습니다.
정말 단순하게, client의 요청을 받아서 원하는 정적 컨텐츠를 제공하면 됩니다.
(정적 컨텐츠: html파일이나 text파일처럼 다른 가공이 필요없이 client에게 응답 할 수 있는 것)
예를 들면, 잘못된 url을 요청하면 404page를 내려주는 방법으로 사용 할 수 있습니다.
하지만 WS로는 한계가 존재합니다. 사용자의 로그인 정보를 통해 해당 사이트에 적절한 배너를 배치하여 사용자 맞춤으로 제공할 수 있으며, 뼈대를 구성한 page에 정보만 변경하여 쉽게 제공하고 싶을 수 있습니다.
WS만 사용한다면, 사용자마다 맞춤 page를 정적 컨텐츠로 미리 준비해야하고 page에 정보가 바뀔때마다 업데이트를 해줘야 합니다
이를 WAS를 통해 해결 할 수 있습니다.
위의 문제점을 해결하기 위해 우리가 할 수 있는 방법은 정보를 동적으로 생성하고, 페이지를 제작하여 제공하면 됩니다. 이를 WAS를 통해 해결 할 수 있습니다.
(DB의 목적은 page용 DB가 아닌 데이터를 저장하는 용도입니다.)
위에서 언급한 것처럼 WAS는 WS의 기능을 대신 할 수 있기 때문에 정적 page를 빼놓지 않고 그렸습니다. 하지만, WAS는 WS와 다르게 조금 크게 그린 것을 확인 할 수 있습니다.
여기서 WAS의 동작 방식에 대해 설명하기 위해 조금 크게 그렸습니다.
즉, client의 요청 정보에 따라, DB의 데이터를 가공하여 동적인 컨텐츠를 제공하는 것이 WAS의 기능입니다.
WAS의 기능을 알았다면 어떻게 WAS가 client 요청을 처리하는지 알아보겠습니다.
먼저 WAS는 servlet Container가 처리하는 방식입니다.
여기서 servlet, container는 무엇을 의미하는지부터 이해하고자 했습니다.
Servlet이란 java에서 request, response를 기반으로 수행하는 자바 표준 명세 API 입니다. java에서는 servlet이라는 표준 명세가 있고, Generic servlet이란 표준 구현 servlet이 존재합니다.
java에서는 web에서 servlet을 자주 사용하는 것을 인지하고, servlet을 구현한 HttpServlet 클래스 파일을 만들었습니다.
이를 통해 client의 요청을 HttpServletRequest, HttpServletResponse로 받아 처리하는 함수를 실행 할 수 있는 것입니다.
container란 spring에서 bean을 관리하는 것으로 bean의 생성/관리/파괴를 대신 담당합니다. bean은 spring이 관리하는 객체로, DB connection 정보, application의 특정 정보와 같은 것을 포함하고 있습니다.
즉, spring에서 bean정보를 등록하면, container가 그 객체 정보를 관리를 맡게 되는데 이를 IoC라고 합니다.
위의 정보를 통해 servlet container가 하는 일을 이해해보면,
1. client의 요청은 servlet을 이용하여 처리.
2. WAS는 servlet container로 servlet을 관리.
로 이해 할 수 있습니다.
WAS에 servlet container가 존재하고, client의 요청을 통해 얻어온 정보로 HttpServletRequest, HttpServletReponse 객체를 생성하여 처리합니다. 여기서 만들어진 Req, Res객체는 container가 Thread를 할당하여 각자 독립적인 환경에서 처리될 수 있도록 합니다.
그럼 우리가 구현한 spring의 로직은 어떻게 servlet container가 알고 처리할까요?
spring boot의 경우 내장 WAS(기본: tomcat)을 사용하여 이러한 연동을 자동으로 처리합니다.
그렇기 때문에, spring boot를 통해 서버를 띄우면 WAS위에 spring이 올라가서 구동된다고 표현하는 것입니다.
만약 jar파일이 아닌 war파일을 사용하여 배포한다면, WAS서버를 따로 구성하고 spring의 web.xml 파일을 통해 servlet에 대한 정보를 제공합니다. WAS는 이를 통해 servlet에 대한 정보를 얻어 servletcontainer가 관리하게 둡니다.
먼저 WAS에서 처리하는 HttpServlet 클래스를 보면,
Service(), doGet(), doPost(), init(), destory()등 서비스 처리 방법과, servlet 생성, 파괴에 대해 구현체가 있다는 것을 확인 할 수 있습니다.
기본적으로 많이 사용하는 tomcat으로 예를 들겠습니다.
tomcat은 open-source로 제공되며 servlet container로 자주 사용됩니다.
기본적으로 위와 같이 작동하며, "load-on-startup"과 같은 설정으로 미리 servlet을 생성할 수 있습니다.
즉, 이러한 작동방식을 하기 위해서는 servlet container가 동작할 수 있는 JVM 환경이 있어야 하고, servlet container에서 client의 요청을 받아 적절한 servlet에게 할당하여 service를 제공해야 합니다.
다음 내용을 그림을 정리하면 다음과 같습니다.
WAS가 이러한 복잡한 로직을 가지고 있기 때문에, WS를 이용해서 처리 할 수 있는 정적인 컨텐츠는 WS에서 처리하도록 두는 방식을 많이 사용한다고 합니다. 하지만, 요즘 WAS의 기능이 좋아져서 WAS로만 처리해도 상관 없다는 글도 자주 보이는 것 같습니다.
WAS와 WS의 기능을 정리하며, spring이 왜 tomcat을 사용해서 편하게 서버를 띄울 수 있는지에 대한 공부가 되었고, servlet과 servlet container에 대한 개념을 잡으며 spring에 대한 공부도 같이 된 것 같습니다.
다음 테크톡 주제도 준비하면서 많은 공부가 되었으면 좋겠습니다.
긴 글 읽어주셔서 감사합니다. 🤗
+ 추가 할 내용이나 부족한 부분이 있다면, 댓글 작성 부탁드립니다! :)