최근 Spring WebFlux에 대해서 공부하려고 마음먹은 찰나 강의를 사거나 듣기전에 대충 어떤것인지 파악하고자 공식문서, 블로그, GPT를 이용하여 개념을 공부하고 있습니다.
다들 정확하고 내용도 깊었지만 공통적으로 소개하거나 요약을할때 너무 어렵게만 설명하거나 표현해놓은 것이 마음에 들지 않았습니다.
심도 깊게 이해하기전에 대략적으로 이해하는 것도 중요하게 생각하는 입장에서 제가 이해한 Spring MVC와 Spring WebFlux 작동방식에 대해서 러프하게 PPT로 그려보았고 추가로 구체적인 차이점에 대해서도 적어보았습니다.
해당 포스팅은 아래 이미지와 Bold 처리된 글만 보면 충분히 차이점을 느낄 수 있을거라고 생각이 됩니다.
I/O 작업이란 외부 자원(네트워크, 디스크 등)과의 통신 및 그 통신에 대한 대기 시간을 의미합니다.
Spring MVC와 Spring WebFlux는 I/O작업 관련 Thread 반환 방식에 대해서 차이가 있었습니다.
Spring MVC와 같은 전통적인 블로킹 방식에서는 I/O 작업을 처리하는 동안 스레드가 그 작업이 완료될 때까지 대기합니다. 이 스레드는 그 동안 다른 요청을 처리하지 못하고 '블로킹'된 상태로 유지됩니다. 그래서 스레드 수가 넘는 요청이 오면 요청이 처리되지 못하고 대기중인 상태가 됩니다. 이 방식에서는 요청(Async 로직이 없다는 가정 하에)에 Thread1이 할당되면 요청에 대한 모든 작업이 끝날때까지 Thread1만 사용되며 작업이 끝날때까지 Thread1을 이용할 수 없습니다.
Spring WebFlux는 이미지에서 보다싶이 스레드가 I/O 작업 중에는 사용되지않고 반환됩니다. 그래서 요청이 아무리 많이 들어오더라도 느려지기야 하겠지만 대기하는 요청없이 모두 처리중인 상태가 됩니다. I/O작업에서 Thread가 필요 없는 이유는 I/O 작업은 외부 자원(네트워크, 디스크 등)과의 통신에 의존하며 작업이 진행되는 동안 CPU가 개입할 필요가 없기 때문입니다. 스레드는 CPU 자원을 사용하여 실제 계산을 수행하는 역할을 하므로, I/O 작업이 끝날 때까지 스레드를 할당하는 것은 비효율적입니다. 이 때문에 논블로킹 방식에서는 I/O 작업 중 스레드를 반환하고, 다른 작업에 재할당하는 방식으로 효율성을 극대화합니다. 그래서 해당 방식은 동일한 요청에 대해서 Thread1, Thread2, Thread3들이 유동적으로 사용 될 수 있습니다.
위 글만 본다면 Node.js나 Spring WebFlux에서 사용되는 Non-Blocking 방식이 절대 대기하지 않는 방식이라는 의미로 오해 할 수 있습니다. '요청이 많아지면 느려지긴한다'는 표현을 정확히 말하자면 스레드 활용 방식이 효율적이라 기존 방식보다 처리속도가 빠를 뿐이지 결국 시스템 자원이 모두 사용중이라면 Non-Blocking 방식 역시 마치 Block 된 것처럼 대기상태에 들어갈 수 있습니다. 그래서 백프레셔(Backpressure - 소비자가 처리할 수 있는 양을 초과하는 데이터가 생산될 때 이를 조절하는 기법)라는 기법을 이용하여 데이터를 원하는 속도로 보내도록 조절하기도 합니다.
이후 강의나 개인적인 테스트를 통해서 알게된 정보가 있으면 포스팅을 업데이트 할 예정입니다.