안녕하세요, 첫 주의 마지막 기술세미나를 맞게 된 손민우입니다. 자료를 준비하고 발표 연습을 하면서 우여곡절이 정말 많았습니다. (발표가 끝난 지금도 생각하면 떨리네요.)

주제를 선택하면서 가장 기본적인 부분에 대해 설명하고 싶었어요. 그래서 Controller에 대해 검색하다 알게 된 Dispatcher Servlet에 대해 발표해보면 어떨까하는 생각을 했던 것 같습니다.

그래서 이번 기술 세미나에서는 MVC의 흐름도에서부터 시작하여 Dispatcher Servlet, 마지막으로 Servlet에 대해 알아보고 결론적으로 개발자에게 어떤 도움을 주는지 알아볼까 합니다.

그럼, 시작해보겠습니다.

1. Spring Web MVC

image

위의 흐름도는 spring docs의 내용을 기반으로 그린 spring web MVC의 흐름도 입니다. 아마 Controller을 검색하다 종종 보신 적이 있으실 겁니다.

image

그리고 이 흐름도에서 개발자에 의해 주로 개발되어지는 부분인 Controller, Repository, Service, Component 입니다.

image

그리고 Dispatcher Servlet을 이해하기 위해서는 먼저 Client와 Controller 사이의 일들에 대해 알 필요가 있습니다.

2. Spring Web MVC 흐름도

그럼 순서대로 설명을 진행하겠습니다.

image

User(Client)가 보내는 Request에는 다양한 정보가 있는데 다음은 그 중 몇 가지입니다.

  • HTTP 메소드 : 동작을 나타내는 메소드를 의미하며 GET , POST , PUT, DELETE 등이 있다.
  • URI : 리소스의 식별자로 “/users” 나 “/products/123” 등이 있다.
  • 이 외에도 HTTP 헤더, 세션 정보 등 다양한 내용이 들어있다.
image

보내진 Request를 받은 Dispatcher Servlet은 받은 내용 중 URI를 Handler Mapping에 보내 Controller들 의 URI List 중에서 동일한 주소를 가진 Controller 찾아 주게 된다.

image

그럼 찾은 Controller로 Request를 보내기 위해 Handler Adapter를 거쳐 Controller로 일 처리를 위임하게 됩니다.

image

그렇게 Controller가 일을 위임받게 되면 개발자가 구현해 놓은 Business Logic을 기반으로 Response를 만들어 반환을 해주게 되는데 이때 View name과 Model을 같이 보내게 됩니다.

image

Response를 받은 Dispatcher Servlet은 View name과 Model을 View Resolver로 보내게 되고 View를 거쳐 최종적으로 User에게 보여질 View를 생성하여 다시 Dispatcher Servlet으로 보내게 됩니다.

image

그렇게 완성한 Response를 다시 User에게 보내게 되면서 한 흐름이 끝나게 됩니다. 위 그림에서 Dispatcher Servlet이 중간에 위치하면서 모든 처리에 대해 중앙 집중적으로 처리한다는 점을 알 수 있습니다.

그리고 웹 서비스는 하나의 요청만 있는 것이 아니기 때문에 다양한 요청에 대해 처리되는 과정도 봐야겠죠?

3. Dispatcher Servlet이 하는 일

다음 그림은 여러 요청이 들어오는 그림입니다. 위의 그림에서 Client와 Dispatcher Servlet, Controller만을 분리하여 그린 그림입니다.

image

위의 그림은 Dispatcher Servlet이 여러 요청들을 받더라도 각 URI에 대해 연결되어지는 Controller에게 일을 위임하고 응답을 받아 User에게 전달하게 됩니다.

image

그리고 우리는 이렇게 중앙 집중적으로 일을 처리하는 패턴을 Front Controller Pattern이라고 합니다.

그런데 왜 Front Controller Pattern의 Servlet을 따로 구현해서 사용할까요?

4. Dispatcher Servlet vs Servlet

그걸 알기 위해서는 이전에 사용되어진 방식을 알아야 합니다.

<img width="500" alt="image"height="300" src="https://raw.githubusercontent.com/Kernel360/blog-image/main/2023/1110/13.png">

위 그림은 일반적인 Servlet을 이용해서 Controller로 요청을 보내는 과정을 보여주는 그림입니다.

Servlet을 통해 요청과 응답을 할 때마다 스레드가 생성이 되면서 멀티 스레딩에 의한 자원 공유로 인해 동기화 문제가 발생하거나 단일 프로세스 시스템 일때 효과를 못 볼 수 있습니다.

<img width="500" alt="image"height="300" src="https://raw.githubusercontent.com/Kernel360/blog-image/main/2023/1110/14.png">

그리고 일반적인 Servlet은 Singleton Pattern으로 구현되어 있어 매 요청마다 쓰레드를 새로 생성하여 일을 처리하게 됩니다. 처리한 이후에 쓰레드는 소멸되지만 인스턴스는 서블릿 컨테이너에 남아 동일한 요청이 다시 오게 되면 인스턴스를 호출해 재사용하게 됩니다.

image

다시 첫 번째 사진을 보니 어떠신가요? Dispatcher Servlet이 왜 필요한지 그리고 어떤 역할을 하고 있는지 느껴지셨나요?

이렇게 Dispatcher Servlet은 기존의 Servlet을 이용하여 여러 요청들을 처리하면서 생길 수 있는 문제를 해결함과 동시에 중앙에서 모든 일을 처리하게 되면서 구조를 단순하게 해주고 유지 보수를 쉽게 해줍니다.

또한 독립적인 모듈화를 통해 확장성도 가지게 됩니다. 결론적으로는 개발자들로 하여금 business logic에 대해 보다 집중할 수 있게 도와주게 되는 것입니다.

5. 정리

정리하자면 Servlet을 통해 통신을 하게 되면 하나의 요청만 하는 것이 아니라면 하나의 프로세스 안에서 여러 개의 쓰레드가 생성이 되게 되고 이러한 멀티 스레드로 인해 자원 공유가 생기고 동기화 문제가 발생하거나 단일 프로세스 시스템 일 때 효과를 못 볼 수 있는 문제가 생길 수 있다. 그리고 서블릿이 여러 개가 있을 경우 모듈화나 확장성에 있어서 제한적일 수 있다.

그렇기 때문에 Singleton Pattern이나 Front Controller Pattern을 활용하여 Dispatcher Servlet을 구현하였고 그로 인해 개발자들은 서비스를 개발하는데 더 집중할 수 있게 되었다.

6. 발표 후기

주제를 준비하면서 주제를 바꿀까하는 생각도 여러번 들었던 것 같은데 마무리를 잘한 것 같아 다행이라고 생각합니다. 더 많은 내용을 공개하고 싶었지만 실제로 구현하는 부분은 아직 실력이 부족한 것 같아 아쉬움 또한 드는 것 같습니다.

다음에 또 이런 기회가 주어진다면 더 좋은 주제와 더 많은 노력을 들여 좋은 발표를 할 수 있도록 정진하겠습니다. 지금까지 글을 읽어주셔서 감사합니다!!

8. 참고 문헌

  • https://aaronryu.github.io/2021/02/14/a-tutorial-for-spring-mvc-and-security/

  • https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-servlet.html#page-title

  • https://gmlwjd9405.github.io/2018/09/14/process-vs-thread.html

  • https://jwdeveloper.tistory.com/291