-
[스프링 인 액션] Chapter 12 - 리액티브 데이터 퍼시스턴스 :: 스프링 데이터의 리액티브 개념 이해하기개발서적읽기/Spring in Action 제 5판 2020. 10. 9. 17:51
이전 포스팅에서는 스프링 WebFlux를 사용해서 리액티브하고 블로킹이 없는 컨트롤러를
생성하는 방법을 알아보았다. 그러나 같이 작동되는 다른 컴포넌트도 블로킹이 없어야 진정한
블로킹 없는 컨트롤러가 될 수 있다. 만일 블로킹 되는 리퍼지터리에 의존하는 스프링 WebFlux
리액티브 컨트롤러를 작성한다면, 이 컨트롤러는 해당 리퍼지터리의 데이터 생성을 기다리느라
블로킹될 것이다. 따라서 컨트롤러로부터 데이터베이스에 이르기까지 데이터의 전체 flow가
리액티브하고 블로킹되지 않는 것이 중요하다.
■스프링 데이터의 리액티브 개념 이해하기
스프링 데이터는 Kay 릴리즈 트레인부터 Reactvie Repository의 지원을 제공하기 시작했다.
Reactvie Repository는 카산드라, 몽고DB, 카우치베이스, Redis 등을 지원한다. 하지만
RDB나 JPA는 지원하지 않는데, 이들은 표준화된 비동기 API를 제공하지 않기 때문이다.
따라서 앞으로 카산드라와 몽고DB를 이용하여 스프링 데이터 리액티브를 공부해볼 것이다.
스프링 데이터 리액티브 개요
Reactvie Repository는 도메인 타입이나 컬렉션 대신, Mono나 Flux를 인자로 받거나
반환하는 메서드를 갖는다.
리액티브와 리액티브가 아닌 타입 간의 변환
기존에 RDB를 사용중일 때도 Reactive Programming을 애플리케이션에 적용할 수 있다.
RDB가 블로킹 없는 Reactive Query를 지원하지 않더라도, 우선 블로킹 되는 방식으로
데이터를 가져와서 가능한 빨리 리액티브 타입으로 변환하여 상위 컴포넌트들이 Reactive의
장점을 활용하게 할 수 있다.
예를 들어, RDB와 스프링 데이터 JPA를 사용한다고 해보자. 이 경우 OrderRepository는
다음과 같은 시그니처의 메서드를 가질 수 있다.
List<Order> findByUser(User user);
이 findByUser()는 블로킹 방식으로 동작한다. 왜냐하면 List가 Reactive 타입이 아니므로
어떤 Reactive 오퍼레이션도 수행할 수 없기 때문이다. 게다가 컨트롤러가 findByUser()를
호출했다면 결과를 리액티브하게 사용할 수 없어 확장성을 향상시킬 수 없다.
이 경우엔 가능한 빨리 Reactive가 아닌 List를 Flux로 변환하여 결과를 처리한다.
List<Order> orders = repo.findByUser(someUser);
Flux<Order> orderFlux = Flux.fromIterable(orders);Mono를 사용할 경우엔 아래와 같이 작성하면 된다.
Order order = repo.findById(id);
Mono<Order> orderFlux = Mono.just(order);이처럼 Mono의 just()나 Flux의 fromIterable(), fromArray(), fromStream()을 사용하면
Repository의 Reactive가 아닌 블로킹 코드를 격리시키고 애플리케이션의 어디서든
Reactive 타입으로 처리하게 할 수 있다.
이번엔 저장하는 경우에 대해서 살펴보자. Mono나 Flux 모두 자신들이 발행하는 데이터를
도메인 타입이나 Iterable 타입으로 추출하는 오퍼레이션을 가지고 있다.
Taco taco = tacoMono.block();
tacoRepo.save(taco);Iterable<Taco> tacos = tacoFlux.toIterable();
tacoRepo.saveAll(tacos);Mono의 block()이나 Flux의 toIterable()은 추출 작업을 할 때 블로킹이 된다.
따라서 이런식의 Mono와 Flux를 사용을 최소화 해야 한다.
블로킹되는 타입을 더 Reactive하게 추출 할 수도 있다. Mono나 Flux를 구독하면서
발행되는 요소 각각에 대해 원하는 오퍼레이션을 수행하는 것이다.
tacoFlux.subscribe(
taco -> {
tacoRepo.save(taco);
}
);tacoRepo의 save는 여전히 블로킹 오퍼레이션이다. 그러나 Flux나 Mono가 발행하는
데이터를 소비하고 처리하는 Reactive 방식의 subscribe()를 사용하므로 블로킹 방식의
일괄처리보다는 더 바람직하다.
'개발서적읽기 > Spring in Action 제 5판' 카테고리의 다른 글
[스프링 인 액션] Chapter 12 - 리액티브 데이터 퍼시스턴스 :: 리액티브 몽고DB 리퍼지터리 작성하기 (0) 2020.10.10 [스프링 인 액션] Chapter 10 - 리액터 개요 :: 리액티브 오퍼레이션 적용하기 (0) 2020.10.04 [스프링 인 액션] Chapter 10 - 리액터 개요 :: 리액터 시작하기 (0) 2020.10.03 [스프링 인 액션] Chapter 10 - 리액터 개요 :: 리액티브 프로그래밍 이해하기 (0) 2020.09.27 [스프링 인 액션] Chapter 9 - 스프링 통합하기 :: 스프링 통합의 컴포넌트 살펴보기 (0) 2020.09.27 댓글