출처 : https://spring.io/reactive
Spring Webflux Framework
- 내부적으로 Reactor 프로젝트와 그의 구현체인 Flux, Mono를 이용한다.
- 어노테이션 혹은 함수형 라우팅/핸들링을 지원한다.
출처 : https://reflectoring.io/getting-started-with-spring-webflux/
특징
- 클라이언트-서버간 반응형(reactive) 어플리케이션 개발을 도와주는 스프링 모듈
- Servlet API기반의 Spring WebMVC를 대체하기 위한 프레임워크이며 non-blocking Reactive Stream을 지원한다.
- Event Loop Model로 동작한다
- Event Driven : 프로그램 실행 흐름이 이벤트에 의해 결정되는 프로그래밍 패러다임. Event가 발생할 때 이를 감지하고 적합한 이벤트 핸들러를 사용해 이벤트를 처리하도록 설계하는 방법으로 Webflux의 Event-loop가 이러한 방식으로 동작한다.
- 사용자 요청 및 application 내부에서 처리해야 하는 작업들은 모두 event라는 함수로 관리되고, event queue에 적재되어 순서대로 처리되는 구조이다.
- event를 처리하는 thread pool이 존재한다. 따라서 순차적으로 event를 처리해서 event loop이라 부르기도 한다.
- event loop은 event queue에서 event를 뽑아 하나씩 처리한다.
- 단일 스레드로 동작하는 이벤트 루프를 여러개 사용하는,
Multi Event Loop
또한 지원된다.
구성요소
Reactor
- Reactive 라이브러리
- Publisher-Subscriber 패턴을 중심으로 동작하며 데이터를 생성하고 가공하고 구독자에게 전달하는 역할을 한다.
출처 : https://bgpark.tistory.com/159
Publisher
- 생산자
- 데이터를 생산
- 생산된 데이터를 소비할 소비자(Subscriber)가 등록(subscribe)될 때까지 아무일도 일어나지 않는다.
- Publisher 측에서 Subscription을 생성하여 Subscriber를 구독한다.
Operator
- 체인 연산자
- 연산자(Operator)는 새로운 생산자(Publisher)를 반환한다
Subscription
- Subscriber가 요청한 데이터를 Subscriber의 onNext를 통해 보내준다
- 요청을 취소할 수도 있다.
Subscriber
- 소비자
- 데이터를 소비한다
- 데이터 가지고 무엇을 할 건지 결정한다
반응형 스트림 처리 과정
- Publisher(생산자)가 Subscriber(소비자)를 subscribe(등록)한다.
- 동시에 Subscriber(소비자)가 Subscription(전달자)을 onSubscribe(등록)한다
- Subscriber(소비자)는 필요할 때 Subscribe(전달자).request(요청)을 통해 Publisher에게 데이터를 요청한다.
- Publisher(생산자)는 요청을 받으면 생성한 데이터를 보낸다
- Subscriber는
onNext
로 데이터를 받는다.
- 모든 요청이 성공적으로 완료되면
onComplete
을 호출하고 흐름을 종료한다.
- 요청이 실패하면
onError
를 호출하고 흐름을 종료한다.
Mono
- Publisher의 한 타입
- 0건 또는 1건의 데이터만 emit하는 Reactor Data Stream 타입
Flux
- Publisher의 한 타입
- 여러 개의 데이터를 emit하는 Reactor Data Stream 타입
Mono, Flux 둘 다 비동기적으로 실행시켜 요청한 결과가 생성되기 전까지 blocking되지 않고 다른 작업을 수행할 수 있다.
BackPressure
- Publisher가 Subscriber에 데이터를 emit하는 속도에 비해 Subscriber가 데이터를 처리하는 속도가 느리면 처리되지 않은 데이터들이 쌓이거나 오버플로우가 발생하고 더 나아가 시스템이 다운되는 일이 발생한다.
- 이런 점들을 제어하기 위한 전략이 Backpressure이다.
- Backpressure는 데이터를 적절하게 제어해 과부하가 발생하지 않도록 예방한다.
- Backpressure를 적용하는 다양한 전략이 존재한다
종류 | 설명 |
---|
GNORE 전략 | Backpressure를 적용하지 않는다. |
ERROR 전략 | Downstream으로 전달할 데이터가 버퍼에 가득 찰 경우, Exception을 발생시킨다. |
DROP 전략 | Downstream으로 전달할 데이터가 버퍼에 가득 찰 경우, 버퍼 밖에서 대기하는 먼저 emit된 데이터부터 Drop시킨다. |
LATEST 전략 | Downstream으로 전달할 데이터가 버퍼에 가득 찰 경우, 버퍼 밖에서 대기하는 가장 최근에(나중에) emit된 데이터부터 버퍼에 채운다. |
BUFFER 전략 | Downstream으로 전달할 데이터가 버퍼에 가득 찰 경우, 버퍼 안에 있는 데이터부터 Drop시킨다. |
WebClient
- Spring WebFlux에서 HTTP Client로 사용되는 비동기적으로 작동하는 모듈
- 비동기에 더해 Non blocking IO방식으로 동작하여 동시성이 높다.
Spring Webflux vs Spring MVC
| Webflux | MVC |
---|
방식 | 논블로킹, 비동기 통신 | 블로킹(Thread per Request), 동기 통신(단, @Async를 이용하여 비동기 통신은 가능) |
쓰레드 블로킹 | X | O |
실행 서버 | Netty | Tomcat |
프로그래밍 패러다임 | 반응형 프로그래밍 | 명령형 프로그래밍 |
쓰레드 개수 | 2 * core | 200 (Tomcat default) |
Webflux사용 목적
- 반응형 프로그래밍을 통해 '높은 처리량'과 '확장성'을 갖는 애플리케이션을 만드는 것
- 동시 사용자의 수가 많을 때의 성능 개선
ref