ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring 비동기 처리 - 2(성능테스트)
    spring/reactive 2021. 6. 5. 11:32

    배경

    비동기 처리를 이용해 한 스레드가 불필요하게 오래 블락된 경우를 개선해보았다. 이제 동기방식으로 스레드를 관리할 때 어떤 문제가 발생할 수 있는지 또 그걸 비동기적으로 어떻게 풀어나갈지 실제로 테스트해보자.

     

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

    토비님의 실습을 참고하며 공부한 내용이다.

     

     

    문제 상황

    클라이언트가 서버1에게 요청을 날리면 서버1은 서버2에게 요청을 날리고 응답이 올 때까지 블락된다. 서버2의 응답이 서버1에 도착하고 서버1이 최종적으로 클라이언트에게 응답을 주는 방식이다. 이때 100개의 요청이 동시에 서버1로 몰리는 경우를 테스트해보자.

     

    요청하는 클라이언트 코드다. 100개의 스레드를 생성해서 CyclicBarrier를 이용해 한번에 요청이 일어나도록 작업했다. 각 요청이 처리되는 시간을 StopWatch를 이용해 측정했고 코드에는 안 나오지면 전체 요청을 처리하기 위한 시간도 측정했다. 결과를 확인해보자.

    마지막 100번째 작업이 처리되는 데 52초가 걸렸고 전체 작업을 처리하는 데도 52초 정도가 걸린 걸 확인할 수 있다. 요청 하나당 0.5초의 시간 걸렸고 다음 작업은 계속 이 시간이 중첩된 걸 알 수 있다. 이는 서버1의 스레드가 한 개인 점과 서버1이 서버2의 결과를 기다렸기 때문임을 알 수 있다.

     

     

    비동기 처리

    위와 같은 문제는 동기 방식으로 생각해보면 어쩔 수 없는 부분이다. 다만, 굳이 서버1이 서버2의 응답을 기다려야 할까라는 의문이 든다. 서버2의 스레드 개수는 100개이지만 현재 방식에서는 서버2의 스레드를 제대로 활용하지 못하고 있다. 서버1은 서버2에게 작업을 요청하고 바로 스레드를 반납하고 서버2의 응답이 오면 다시 스레드를 할당하는 방식이 위 아키텍처 방식이다. 

    결과

    서버1
    서버2

    로그를 통해 실제 작업시간이 0.8정도로 매우 단축된 걸 확인할 수 있다. 또한 서버1의 작업스레드 개수는 1~2개 정도만 증가한데 비해 서버2의 작업스레드는 110개 이상으로 최대의 효율을 끌어올렸다.(Java Mission Control 활용)

     

    DeferredResult 및 콜백 등록하기

    ListenableFuture에 콜백을 등록할 때 그 결과가 DeferredResult에 담기도록 설정하면 콜백을 수행한 결과가 최종적으로 반환된다. 콜백에서 또 다른 작업을 수행해도 최종결과만 DeferredResult에 등록되게 한다면 비동기적으로 계속 작업을 걸 수 있다.

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

    Spring 비동기 처리 - 3(WebClient와 Reactor)  (0) 2021.06.07
    Spring 비동기 처리 - 1(스레드 작업 분리)  (0) 2021.06.03
    Reactive Streams 구현  (0) 2021.06.01
    Observer 패턴  (0) 2021.06.01

    댓글

Designed by Tistory.