ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring 비동기 처리 - 3(WebClient와 Reactor)
    spring/reactive 2021. 6. 7. 10:43

    배경

    비동기 처리를 이용해 성능을 개선했다. 이제 Reactive Streams를 구현한 스프링의 Reactor API와 비동기 통신을 위한 WebClient를 활용해보자.

     

    AsyncRestTemplate -> Webclient

    DeferredResult, Future -> Reactor API(Mono, Flux)

     

    https://www.youtube.com/watch?v=bc4wTgA_2Xk&list=PLv-xDnFD-nnmof-yoZQN8Fs2kVljIuFyC&index=1

    마찬가지로 토비님의 실습을 열심히 따라하며 공부한 내용이다.

     

    의존성 분석

    spring boot webflux 의존성을 추가하면 위와 같이 의존성이 추가된다. spring-webflux에 앞으로 사용할 Webclient, Reactor API가 모두 들어 있다. 위 모듈에서 특별한 점은 내장서버로 tomcat이 아닌 netty를 사용하는 점이다. tomcat은 동기방식의 서버를 고려해 스레드풀의 기본크기가 200으로 크게 잡혀 있는 반면 netty는 20개 정도의 worker스레드만을 배치해 경량서버를 구현했다. 그만큼 비동기 작업에서 효율적이라고 생각한다.(자세한 비교는 나중에 기회가 되면^^)

     

    Mono 버전

    코드

    테스트는 지난 2편과 동일하게 동작한다. 8080번 서버1로 100개의 클라이언트 요청을 보내고 서버1은 8081번 서버2에게 비동기적으로 작업을 위임하고 서버2로부터 결과가 리턴되면 그때 클라이어언트에게 리턴 결과를 반환한다. 다만, AsyncRestTemplate이 서버2로 작업을 하는 역할을 WebClient가 대체하고 결과를 Future로 연결하고 DeferredResult에 작업을 예약하는 과정을 Mono로 리턴함으로써 대체했다.

     

    결과

    tomcat 서버2 8081
    netty 서버1 8080

     

    100번의 요청에도 netty서버의 스레드는 25개 이하로 비동기적인 작업을 처리했다. 작업시간이 0.5초가 걸리는 tomcat서버는 각 스레드를 최대로 활용해 100개의 요청을 처리했고 최종 결과는 0.9초로 자원을 최대로 활용한 성능 최적화 결과를 얻었다! (위 그래프는 Java Mission Control 사용)

     

    동작 방식

    방금 사용한 Mono는 CorePublisher를 구현했고 CorePublisher는 Reactive Streams의 Publisher를 구현했다. 즉, Reactive Streams의 Publisher 동작방식을 기대할 수 있다. 

     

    Mono는 이벤트가 발생했을 때 수행할 동작을 정의하고 Subscriber가 Publisher의 subscribe()를 호출한 순간 정의한 동작과 함께 Subscriber의 onSubscribe()를 수행하도록 한다. 즉, WebClient의 get().uri()가 비동기적으로 수행되고 그 후행 작업을 Mono에 담아 놓으면 나중에 Subscriber가 subscribe()를 수행 시 나머지 이벤트가 발생하는 것이다. 이때 우리가 Mono만 잘 정의하여 return하게 되면 첫 이벤트가 끝난 시점에 스프링이 자동으로 subscribe()를 호출해주는 구조다.

     

    - 클라이언트가 서버1 rest()요청

    - WebClient 비동기적 실행(서버1이 서버2로 요청) 및 Mono로 작업 예약

    - 서버2의 작업이 끝나고 서버1로 응답하면 스프링이 Mono의 subscribe()호출

    - 정해진 작업 수행 후 서버1에서 클라이언트로 응답

     

    마치며

    Flux 버전 추가 예정이다. 이제 reactor에 대한 기초적인 틀은 잡은 것 같다!

    'spring > reactive' 카테고리의 다른 글

    Spring 비동기 처리 - 2(성능테스트)  (0) 2021.06.05
    Spring 비동기 처리 - 1(스레드 작업 분리)  (0) 2021.06.03
    Reactive Streams 구현  (0) 2021.06.01
    Observer 패턴  (0) 2021.06.01

    댓글

Designed by Tistory.