ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring 비동기 처리 - 1(스레드 작업 분리)
    spring/reactive 2021. 6. 3. 18:08

    배경

    웹서버로 요청이 들어오고 응답이 나가기까지 과정을 간단하게 도식화했다. 요청이 들어온 경우 스레드풀에서 스레드를 할당 받고 비즈니스로직을 수행한 후 적절한 데이터와 함께 응답을 보낸다. 탐켓의 기본 설정만 따르는 경우 스레드풀로부터 할당받은 스레드는 요청이 들어온 뒤부터 응답이 나갈 때까지 반납되지 않는다. 비즈니스로직이 단순히 WAS내에서만 동작하는 로직이라면 큰 문제가 없겠지만 외부 DB와 통신하거나 다른 노드와 작업하는 로직을 포함하게 된다면 스레드는 비교적 많은 시간을 반납되지 못한 상태로 남게 된다. 

     

    서버로의 요청이 갑자기 몰려 스레드풀의 모든 스레드를 할당한 상태에서 대부분의 작업스레드가 외부IO를 수행하느라 반납이 지연되는 상황이라면 서버의 응답성은 현저하게 낮아질 것이다. 이번 작업에서 탐켓의 스레드를 비즈니스로직과 non-blocking방식으로 동작하도록 분리해보자.

     

    @Async를 이용해서 분리하기

    시나리오는 /async로 요청이 오면 먼저 스레드풀에서 스레드가 할당되어 Hello, tomcat Thread를 출력하고 비동기적으로 asyncService메서드를 수행하고 탐켓스레드는 먼저 그 결과를 리턴하는 것이다.

    요청을 보내고 그 로그를 확인해보면 스레드가 구분되었고 비동기적인 처리가 이루어진 걸 확인할 수 있다. 성공^^       (@Configuration이 붙은 클래스에 @EnableAsync를 붙여야 @Async는 동작한다. 또한 작업을 위임할 스레드 전략을 어떻게 구사할지 깊게 공부하고 신중하게 생각해보자)

     

    return을 callable 콜백으로 처리하기

    이번에는 return문에 콜백을 넘겨 새로운스레드가 할당되어 콜백을 처리하도록 만들었다(스프링이 반환형을 보고 알아서 다해준다...) 결과를 확인해보자.

    log의 실행스레드를 보면 새로운 스레드가 생성되어 작업을 수행한 걸 확인할 수 있다. 또한 응답을 위한 작업스레드가 위에서는 요청을 처리한 스레드인 반면 지금은 새로운 작업스레드가 응답을 처리한 걸 확인할 수 있다.

     

    마치며

    요청을 처리하기 위해 스레드를 분할해서 작업했다. 왠지 성능이 굉장히 좋아질 것 같은 느낌이 들지만 사실 현재까지 진행한 작업은 모두 WAS내의 스레드를 이용했다. 즉, 성능업을 위해 작업스레드풀을 만드는 작업은 결국 탐켓스레드풀을 줄여야만 가능하다는 점이다. 이제 이런 한계를 또 어떻게 극복해나갈지 궁굼하다!

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

    Spring 비동기 처리 - 3(WebClient와 Reactor)  (0) 2021.06.07
    Spring 비동기 처리 - 2(성능테스트)  (0) 2021.06.05
    Reactive Streams 구현  (0) 2021.06.01
    Observer 패턴  (0) 2021.06.01

    댓글

Designed by Tistory.