-
Spring WebFlux 개요Spring Reactive Web Application/Spring WebFlux 2023. 8. 22. 23:00반응형
Spring WebFlux
- 리액티브 웹 애플리케이션 구현을 위해 Spring 5.0부터 지원하는 리액티브 웹 프레임워크입니다.
- 비동기 Non-Blocking I/O 방식으로 적은 수의 스레드로 대량의 요청을 안정적으로 처리합니다.
- Reactive Streams의 구현체 중에 하나인 Reactor에 의존하여 비동기 로직을 구성하고 리액티브 스트림을 제공합니다.
- Reactor 기반이지만 RxJava 등 다른 리액티브 확장 라이브러리를 쉽게 적용할 수 있습니다.
Spring WebFlux 기술 스택
http://spring.io/reactive - Non-Blocking I/O 방식으로 동작하는 Netty 등의 서버 엔진에서 동작합니다.
- 기본 서버 엔진이 Netty이지만 Jetty나 Undertow 같은 서버 엔진에서 지원하는 리액티브 스트림즈 어댑터를 통해 리액티브 스트림즈를 지원합니다.
- WebFilter를 이용해 Spring Security를 사용합니다.
- 데이터 액세스 계층까지 Non-Blocking I/O를 지원할 수 있도록 Spring Data R2DBC 및 NoSQL 모듈을 사용합니다.
Spring WebFlux의 요청 처리 흐름
- 클라이언트로부터 요청이 들어오면 Netty 등의 서버 엔진을 거쳐 HttpHandler가 들어오는 요청을 전달 받습니다. 서버 엔진마다 주어지는 ServerHttpRequest와 ServerHttpResponse를 포함하는 ServerWebExchange를 생성한 후 WebFilter 체인으로 전달합니다.
- ServerWebExchange는 WebFilter 체인에서 전처리 과정을 거친 후 WebHandler 인터페이스의 구현체인 DispatcherHandler에게 전달됩니다.
- Spring MVC의 DispatcherServlet과 유사한 역할을 하는 DispatcherHandler에서는 HandlerMapping List를 원본 Flux의 소스로 전달 받습니다.
- ServerWebExchange를 처리할 핸들러를 조회합니다.
- 조회한 핸드러의 호출을 HandlerAdapter에게 위임합니다.
- HandlerAdapter는 ServerWebExchange를 처리할 핸들러를 호출합니다.
- Controller 또는 HandlerFunction 형태의 핸들러에서 요청을 처리한 후 응답 데이터를 리턴합니다.
- 핸들러로부터 리턴받은 응답 데이터를 처리할 HandlerResultHandler를 조회합니다.
- 조회한 HandlerResultHandler가 응답 데이터를 적절하게 처리한 후 response로 리턴합니다.
Note. 실제 핸들러에서 리턴되는 것은 응답 데이터를 포함하고 있는 Flux 또는 Mono Sequence이기 때문에 메서드 호출을 통해 리턴된 Reactor Sequence가 즉시 어떤 작업을 수행하지는 않습니다.
Spring WebFlux 핵심 컴포넌트
HttpHandler
다른 유형의 HTTP 서버 API로 request와 response를 처리하기 위해 추상화된 handle() 메서드만 가집니다.
public interface HttpHandler { Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response); }
HttpHandler의 구현체인 HttpWebHandlerAdapter 클래스는 handle() 메서드의 파라미터로 전달받은 ServerHttpRequest와 ServerHttpResponse로 ServerWebExchange를 생성한 후에 WebHandler를 호출하는 역할을 합니다.
WebFilter
Spring MVC의 서블릿 필터(Servlet Filter)처럼 핸들러가 요청을 처리하기 전에 전처리 작업을 할 수 있도록 해줍니다. 주로 보안이나 세션 타임아웃 처리 등 애플리케이션에서 공통으로 필요한 전처리에 사용됩니다.
public interface WebFilter { Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain); }
파라미터로 전달받은 WebFilterChain을 통해 필터 체인을 형성하여 원하는 만큼의 WebFilter를 추가할 수 있습니다.
HandlerFilterFunction
함수형 기반의 요청 핸들러에 적용할 수 있는 Filter입니다.
@FunctionalInterface public interface HandlerFilterFunction<T extends ServerResponse, R extends ServerResponse> { Mono<R> filter(ServerRequest request, HandlerFunction<T> next); ... }
파라미터로 전달받은 HandlerFunction에 연결됩니다.
Note. WebFilter와 HandlerFilterFunction의 차이점
WebFilter는 애플리케이션 내에 정의된 모든 핸들러에 공통으로 동작합니다. 따라서 애너테이션 기반의 요청 핸들러와 함수형 기반의 요청 핸들러에서 모두 동작합니다. 반면에 HandlerFilterFunction은 함수형 기반의 핸들러에서만 동작합니다.
DispatcherHandler
WebHandler 인터페이스의 구현체로서 Spring MVC의 DispatcherServlet처럼 중앙에서 먼저 요청을 전달받은 후에 다른 컴포넌트에 요청 처리를 위임합니다. DispatcherHandler 자체가 Spring Bean으로 등록되도록 설계되었으며, ApplicationContext에서 HandlerMapping, HandlerAdapter, HandlerResultHandler 등의 요청 처리를 위한 위임 컴포넌트를 검색합니다.
HandlerMapping
request와 handler object에 대한 매핑을 정의하는 인터페이스이며, HandlerMapping 인터페이스를 구현하는 구현 클래스로는 RequestMappingHandlerMapping, RouterFunctionMapping 등이 있습니다.
public interface HandlerMapping { ... Mono<Object> getHandler(ServerWebExchange exchange); }
getHandler() 메서드는 파라미터로 입력받은 ServerWebExchange에 매치되는 handler object를 리턴합니다.
HandlerAdapter
HandlerMapping을 통해 얻은 핸들러를 직접적으로 호출하는 역할을 하며, 응답 결과로 Mono<HandlerResult>를 리턴받습니다. Spring 5.0 Reactive 스택에서 지원하는 HandlerAdapter 구현 클래스로 RequestMappingHandlerAdapter, HandlerFunctionAdapter, SimpleHandlerAdapter, WebSocketHandlerAdapter가 있습니다.
public interface HandlerAdapter { boolean supports(Object handler); Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler); }
- supports(Object handler): 파라미터로 전달받은 handler object를 지원하는지 체크합니다.
- handle(ServerWebExchange exchange, Object handler): 파라미터로 전달받은 handler object를 통해 핸들러 메서드를 호출합니다.
Spring WebFlux의 Non-Blocking 프로세스 구조
Non-Blocking I/O 방식의 Spring WebFlux는 요청 처리 방식으로 이벤트 루프 방식을 사용합니다. 이로 인해 스레드가 차단되지 않으며, 적은 수의 고정된 스레드 풀을 사용해서 더 많은 요청을 처리합니다.
- 클라이언트로부터 들어오는 요청을 요청 핸들러가 전달받습니다.
- 전달받은 요청을 이벤트 루프에 푸시합니다.
- 이벤트 루프는 네트워크, 데이터베이스 연결 작업 등 비용이 드는 작업에 대한 롤백을 등록합니다.
- 작업이 완료되면 완료 이벤트를 이벤트 루프에 푸시합니다.
- 등록한 콜백을 호출해 처리 결과를 전달합니다.
이벤트 루프는 단일 스레드에서 계속 실행되며, 클라이언트의 요청이나 데이터베이스 I/O, 네트워크 I/O 등 모든 작업들이 이벤트로 처리되기 때문에 이벤트 발생 시 해당 이벤트에 대한 콜백을 등록함과 동시에 다음 이벤트 처리로 넘어갑니다.
Note. Spring WebFlux의 스레드 모델
Spring WebFlux는 Non-Blocking I/O를 지원하는 Netty 등의 서버 엔진에서 고정된 크기의 스레드(일반적으로 CPU 코어 개수만큼의 스레드 생성, 최소 4개)를 생성해서 대량의 요청을 처리합니다.
[참고 정보]
반응형'Spring Reactive Web Application > Spring WebFlux' 카테고리의 다른 글
예외 처리 (0) 2023.09.16 R2dbcEntityTemplate (0) 2023.09.10 Spring Data R2DBC (0) 2023.09.09 함수형 엔드포인트(Functional Endpoint) (0) 2023.08.26 애너테이션 기반 컨트롤러(Annotated Controller) (0) 2023.08.26