1. tomcat에서 dispatcher servlet은 왜 하나인가?
공부를 하다보니 왜 하나인가? 라는 질문은 적절하지 않다고 생각되었다.
이것을 완벽하게 설명하기 위해서 dispatcher servlet이 둘 이상일 때 효율성에 관련된 내용을 찾아보아야했지만
열심히 논문과 같은 부분을 뒤져본 결과 dispatcher servlet, 더 나아가서 Front Controller pattern이 효율적으로 더 낫다는 내용의 정량적 비교에 대한 논문을 찾지 못했기 때문이다.
그렇지만 공부를 하면서 Front Controller의 장점에 대한 내용은 많이 볼 수 있었기에 이에 대해 정리해보려 한다.
Front Controller Pattern
이는 웹 어플리케이션에서 구현되는 디자인 패턴 중 하나로,
웹 사이트에서 발생하는 모든 요청을 한 곳에서 처리하는 방식의 소프트웨어 디자인 패턴이다.
성능적 장점
- 중앙 집중화된 요청 처리: DispatcherServlet을 통해 모든 요청을 한 곳에서 관리함으로써 애플리케이션 전반에 걸친 일관된 처리 방식과 더 나은 제어를 제공. 이는 보안, 인증, 로깅 등의 공통 작업을 중앙에서 수행하기 때문에 각 요청마다 중복되는 작업이 줄어든다.
- Thread-safe 설계 (Stateless): 단일 DispatcherServlet이 여러 요청을 동시에 처리. 각 스레드는 요청에 맞게 자체 스택을 사용하므로, 다수의 요청이 들어와도 스레드 충돌이 발생하지 않는다. 이를 통해 스레드 안전성과 비동기 처리의 이점이 보장된다.
- 복잡도 감소 : 페이지마다 별도의 컨트롤러를 두는 대신, 단일 Front Controller를 사용함으로써 코드 중복을 줄이고, 새 요청 처리 로직을 추가할 때도 코드 수정 범위가 최소화된다. 이는 특히 큰 규모의 웹 애플리케이션에서 성능 및 유지보수 측면에서 큰 이점을 제공
단일 Front Controller의 효율성
- 관리 간소화: 여러 개의 컨트롤러를 두는 경우 각 요청마다 별도의 컨트롤러를 관리해야 하지만, 단일 DispatcherServlet을 사용하면 요청 처리 로직을 통합적으로 관리할 수 있어 애플리케이션의 구조적 복잡성을 줄일 수 있다.
- 확장성: 이 패턴은 확장성을 높이는데, 새로운 핸들러나 기능을 추가할 때도 중앙 관리에서 이루어지므로 추가적인 복잡성 없이도 애플리케이션을 쉽게 확장할 수 있다. 대규모 애플리케이션에서 더 큰 이점을 제공한다.
2. Dispatcher Servlet의 소속은 어디일까?
공부를 하다보니 많은 사람들이 소개한 그림들 중에서 dispatcherServlet의 소관이 다른 것처럼 그려진다.
누군가는 이를 Servlet Container에, 누군가는 이를 Spring Container에 소속시킨다.
그렇다면 정말 어디에 있는 것일까?
답을 말하자면 DispatcherServlet은 말 그대로 Servlet이기에 Servlet Container의 서블릿이다.
하지만 그와 동시에 Spring Container와도 긴밀하게 연관되어 있는 컴포넌트이다.
2 - 1 . Servlet Container (Tomcat) 의 관점
- Dispatcher Servlet은 Servlet 인터페이스를 구현한 Spring만의 서블릿 구현체이다.
- Tomcat은 Servlet 인터페이스를 기반으로 하는 모든 서블릿을 관리한다.
이는 Dispatcher Servlet 또한 마찬가지이다.
2 - 2 . Spring Container의 관점
- DispatcherServlet은 Spring 애플리케이션의 진입점이자, 모든 요청을 적절한 핸들러로 라우팅하는 역할을 한다.
DispatcherServlet은 내부적으로 Spring Container(즉, IoC Container)와 상호작용하며, 요청을 처리하기 위해 여러 Spring Bean (컨트롤러, 서비스 등)을 사용한다. - 그리고 Dispatcher Servlet은 아래와 같이 FrameworkServlet, 그 위로 더 올라가면 ApplicationContextAware의 구현체이다.
즉, Dispatcher Servlet의 소속은 Servlet Container이지만, 구현 자체는 Spring Container의 구현체임을 볼 수 있다. 이 구조는 Servlet Container와 Spring Container의 결합을 잘 보여주며, Servlet Container는 DispatcherServlet을 실행시키고, Spring Container는 이 서블릿 내부에서 의존성을 관리하며 동작하게 한다.
3. Event Loop와 같은 비동기처리와
dispatcher servlet에서 사용된 Front Controller 패턴의 차이점?
3 - 1. DispatcherServlet에서의 비동기 처리
Spring MVC에서 DispatcherServlet은 기본적으로 동기 방식으로 설계되었지만, Spring 3.2부터 비동기 요청 처리를 지원한다. 이는 서블릿 컨테이너의 서블릿 3.0 스펙에 기반한 기능으로, 요청이 들어왔을 때 스레드를 블로킹하지 않고 비동기적으로 응답을 처리할 수 있도록 설계되었다.
이 비동기 처리 방식에서는 요청이 들어오면 서블릿이 요청을 즉시 처리하지 않고, 백그라운드에서 실행될 작업을 등록한 후, 해당 작업이 완료되었을 때 스레드를 다시 할당하여 응답을 반환한다. 이를 통해 비동기적인 작업을 수행하면서도 멀티스레드 환경을 활용할 수 있다.
3 - 2. Event Loop의 비동기 처리
Node.js의 Event Loop는 본질적으로 싱글 스레드에서 동작하지만, I/O 작업이나 타이머와 같은 비동기 작업은 libuv 라이브러리를 통해 백그라운드에서 멀티스레드로 처리된다. 메인 이벤트 루프는 이러한 작업이 완료되었을 때 콜백을 실행하는 구조이다. 따라서 Node.js는 내부적으로 멀티스레드를 활용하지만, 외부적으로는 싱글 스레드 모델로 보여진다.
3 - 3. 두 방식의 차이
- 스레드 관리: DispatcherServlet은 각 요청마다 새로운 스레드를 할당하여 동작하는 구조. 이는 멀티스레드 환경에서 동작하고, 동시에 다수의 요청을 처리할 수 있는 방식이다. 반면, Event Loop는 싱글 스레드로 동작하면서도 백그라운드에서 멀티스레드를 사용하여 비동기 작업을 처리한다.
- 비동기 처리 모델: DispatcherServlet은 비동기 처리를 위해 스레드 풀을 사용하여 각 요청을 처리한다. 그러나 요청이 비동기 작업일 경우, 해당 작업이 완료될 때까지 서블릿이 블로킹되지 않고 다른 작업을 처리할 수 있다. 반면, Event Loop는 싱글 스레드 모델이므로 메인 스레드가 블로킹되지 않고, 모든 비동기 작업이 완료될 때까지 이벤트 큐에 작업을 등록한 후 처리가 완료되면 콜백으로 연결한다.
3 - 4. 결론: Dispatcher Servlet도 비동기인가?
결론적으로 DispatcherServlet도 비동기 처리를 지원하며, 멀티스레드 환경에서 동작한다. 비동기 처리를 위해 백그라운드에서 작업을 처리하고, 스레드가 차이나는 방식에서 이벤트 루프와 차이가 있을 뿐, 근본적으로는 비동기적 성격을 가지고 있다. Event Loop는 기본적으로 싱글 스레드 기반으로 동작하지만, 백그라운드에서 멀티스레드 처리를 하는 반면, DispatcherServlet은 멀티스레드 기반에서 동기 및 비동기 작업을 모두 처리할 수 있는 방식이다.
따라서 두 방식 모두 비동기 처리 모델이지만, 스레드 모델에서 차이가 있는 것이다.
+ 추가)
Node.js의 Event Loop를 엄밀하게 말해 Front Controller 패턴이라고 부르기는 어렵다. Event Loop는 비동기 프로그래밍 모델로 설계된 시스템이고, Front Controller는 중앙 집중형 요청 처리 패턴이다. 둘 다 중앙화된 요청 처리라는 공통점이 있지만, 목적과 적용되는 상황이 다르다.
Event Loop는 비동기 작업의 효율적 관리 및 처리에 중점을, Front Controller는 HTTP 요청과 같은 외부 요청을 중앙에서 처리하는 데 중점을 둔다.
https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-servlet.html
'연재작 > WEB - BE' 카테고리의 다른 글
Spring Bean Deep Dive (0) | 2024.12.02 |
---|---|
디렉토리 구조와 Facade 패턴 (1) | 2024.11.19 |
JVM Runtime Data Area, Singleton과 Race Condition (1) | 2024.11.15 |
Spring bean (3) - 의존성 주입, Spring Framework의 의존성 관리 (0) | 2024.10.23 |
Spring bean (2) - Singleton, Bean (0) | 2024.10.11 |