티스토리 뷰

반응형

흔히 대용량 트래픽이 몰리는 서비스의 회사 스택을 보면 webFlux란걸 볼 수 있습니다. 그리고 실제 여러 글들에서 볼 수 있는 퍼포먼스 비교 분석 그래프를 보면 그 차이는 눈에띄게 차이가 납니다.

그렇다면 webFlux란 뭘까요? webFlux는 reactive programming을 지원하는 프레임워크로 비동기를 사용해 대용량 처리를 적은 자원으로 매우 빠르게 동시 처리하는 성능을 보여줍니다. 

 

그렇다면 무조건 좋은 걸까요? 답을 말씀드리자면 그렇진 않습니다.

 

그렇다면 비동기가 좋은 경우는 어떤 경우일까?

먼저 어떤 경우에 좋은지 알기 위핸 사전 개념인 비동기와 동기 블로킹 논블로킹에 대해 알고 있을 필요가 있습니다. 

https://golf-dev.tistory.com/24

 

<자바 고급스터디 5주차 - 2부> 자바는 Synchronized / Blocking 으로 동작한다?

정확히 말하자면 자바는 Synchronous / blocking 방식을 지원하는 언어다. 그렇다면 Synchronous / blocking이란 무엇일까? 그리고 반대 되는 Asynchronous / non-blocking에 대해서도 알아보자 Synchronous / Blocking 먼저

golf-dev.tistory.com

다음 글을 참고해서 공부해보시길 바랍니다.

 

비동기가 동기로 동작하는 애플리케이션 보다 좋은 경우는 다음과 같습니다.

  1. 트래픽이 몰리는 경우
  2. 적은 자원으로 많은 데이터를 처리해야하는 경우
  3. cpu bound 프로세스가 아닌경우

 

* cpu bound란?

연산이 굉장히 많이 필요한 상황을 말합니다. 대표적으로 이미지 프로세싱 작업이 있고 이러한 경우 I/O burst가 계속 수행됩니다. 이러한 경우에 연속된 I/O burst 가 발생하여 스레드가 계속해서 연산을 해야해 다른 작업을 할 수 없고 그렇게 된다면 다른 작업을 할 수 없기 때문에 비동기의 이점을 갖을 수 없습니다. 또한 이 과정에서 Context switching이 많이 발생하기 때문에 성능이 동기로 동작할 때 보다 저하될 가능성도 있습니다.

 

여기서 오해를 집고 넘어가자면 비동기는 적은 자원으로 많은 요청을 동시처리하기 위해 나온 것이기 때문에 위 두 상황에 대해 빠른 것입니다. 절대 비동기 자체가 동기로 동작하는 애플리케이션 보다 빠른게 아닙니다.

그렇다면 왜 이 경우에 빠른지에 대해 알아보도록 합시다. 

 

이해하기 위해 대표적으로 webflux에 netty 엔진과 mvc의 servlet(tomcat)에 동작 방식을 보면 쉽습니다. 

Thread per Request model

위 모델은 하나의 thread가 한번에 하나의 요청을 처리합니다. 그렇기 때문에 여러 요청이 들어오면 각각 Thread를 할당 받아 서버로 전달하고 Blocking I/O 처리를 하는 동안 Thread는 아무것도 하지 않고 대기상태가 됩니다. 이러한 방식은 요청마다 스레드가 생겨야 하며 그렇게 Thread Pool의 크기를 키우게 되면 운영체제 성능 저하가 되거나 Core 수 이상의 많은 Thread가 사용될 경우 Context Switching이 발생하며 성능 자체가 떨어지게 됩니다. 

 

그렇기 때문에 요청이 많아짐에 따라 모델의 단점이 들어나게 됩니다. 

 

반면에 webflux는 어떨까요? 

reactive Programming model

Reactive 모델은 이벤트 그룹을 형성하여 요청을 이벤트 그룹의 이벤트 루프가 비동기로 처리하며 요청을 처리하는 동안에도 이벤트 루프는 쉬지않고 계속 요청을 받아 처리합니다. 그렇기 때문에 적은 Thread로 높은 동시성을 얻을 수 있으며 Thread 개수를 적게 써 운영체제 성능 저하도 막을 수 있습니다. 

 

결론적으로 많은 요청을 처리하는 상황에서는 비동기를 쓰는게 효율적입니다. 

 

그렇다면 비동기를 썼을 때 주의할 점은 무엇일까요?

 

비동기는 우선 여러 스레드가 독립적으로 작업하기 때문에 디버깅을 하기가 어렵습니다. 순차적으로 처리 되지 않기 때문에 더더욱 디버깅을 하는데 어려움이 있습니다. 실제로 필자는 WebClient를 이용해서 많은 데이터를 처리할 때 스레드가 독립적으로 동작하면서 예상치 못하게 작업 큐 사이즈가 꽉차 데이터 보내는데 실패한 이력이 있는데 이 때 원인을 디버깅으로 찾기 힘들었던 기억이 있었습니다. 

 

또한 비동기를 사용하였을 때 독립적으로 여러 작업들을 스레드가 작업하기 때문에 context switching이 자주 발생할 수 있습니다. 

결론

결론적으로 상황에 따라 적절하게 비동기와 동기를 나눠서 사용해야합니다. 트래픽이 적은 상황에서 만약 webflux 같은 개념을 사용하게 된다면 성능도 챙길 수 없으면서 진입 장벽이 높아 개발에 많은 어려움만 겪게 될 것입니다. 또한 데이터 정합성이 매우 중요한 API 개발 시에는 오히려 순차적으로 동작하는 동기 방식이 정합성을 높이는데 도움을 줄 수 있습니다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함