티스토리 뷰

반응형

Node.js와 Spring MVC(혹은 다른 웹프레임워크)의 비교를 찾아보면 Node.js가 성능과 효율면에서 장점으로 언급되는 경우가 많습니다. 그럼 Node.js는 Spring MVC에게 성능상 우위에 위치하는 걸까요? Node.js의 이런 장점들이 언급되는 이유, 그리고 한계는 어떠한 것이 있는지 알아보겠습니다.

 

핵심적인 차이점을 알기 위해서는 Node.js와 SpringMVC의 다중요청 처리 방식에 대하여 먼저 이해해야 합니다.

 

Spring MVC의 다중요청 처리

Spring MVC는 Thread를 여러개 두어 (Multi-Thread) 다중요청을 동시에 처리합니다. 각 요청마다 별개의 Thread가 해당 요청을 응답까지 책임지는 구조입니다. 

 

마치 식당에서 여러명의 웨이터(server)가 여러 손님(client)들의 요청을 하나씩 분담하는 구조입니다. 이러한 방식에서 많은 웨이터를 두면 손쉽게(?) 많은 손님들의 요청을 동시에 처리할 수 있습니다. 다만, 일반적인 식당에서는 웨이터가 손님을 직접적으로 대응하는 시간보다 주방(kitchen)에서 음식을 조리하는 시간이 더 오래 걸리기 마련입니다. 주방에서 조리하는 시간에 웨이터들이 음식이 나오기만을 하염없이 기다린다면 식당 주인 입장에서 자원의 낭비가 수반되는 방식입니다.

 

Spring MVC의 Multi-Thread방식에서 I/O 작업이 수반된다면 위의 예제와 같은 자원의 낭비가 발생됩니다. Thread가 수행하는 요청과 응답에 대한 일처리에 비하여, I/O 작업은 훨씬 긴 작업시간을 가지고 있고 이러한 시간동안 Thread들이 블로킹되기 때문입니다. Thread의 갯수가 증가될때마다 컨텍스트 스위칭이 빈번하게 일어나게 될 것이고 이로 인한 성능 저하도 야기 될 수 있습니다. 

 

Node.js의 다중요청 처리

반면에 Node.js는 단 한개의 Thread로 (Single-Thread) 모든 요청을 처리합니다.

 

 

(이 그림은 이해를 위한 예제일 뿐이지 실제 싱글 쓰레드는 이것보다 훨씬 더 빠르게 움직입니다.)

한개의 Thread만으로도 Spring MVC의 처리속도와 비견될 수 있는 이유는 Node.js가 완전한 비동기-논블러킹 방식의 I/O 작업을 수용하기 때문입니다. 상대적으로 긴 시간이 소요되는 I/O작업을 기다리지 않고 client의 요청과 응답만을 담당하기 때문에 더 적은 자원으로도 높은 성능을 기대할 수 있습니다. (사실 Single-Thread 방식은 Node.js의 특징이라기 보다는 Javascript의 특징이라고 보는게 맞습니다.)

 

+ 추가적으로 단 한개의 Thread만이 운용되기 때문에 기존 Multi-Thread 방식의 동기화 문제에서 완전히 자유롭습니다. 이로 인한 개발편의성의 이점도 얻을 수 있습니다.

 

그래서 Node.js가 Spring MVC보다 성능상 유리할까?

Node.js가 Spring MVC보다 성능상 우위에 있다라고 말하기 위해서 몇가지 전제사항이 있습니다.

 

1. 다중처리를 동시에 처리하도록 요구된다.

2. 많은 I/O 작업을 수행한다.

3. 단순한 CPU 작업만을 진행한다.

 

이같은 전제사항은 오늘날의 '전형적인' 웹 애플리케이션의 특징입니다. Node.js가 다른 웹프레임워크에 비해서 성능상 우위에 있다고 쉽게 거론되는 이유는 Node.js가 이러한 '전형적인' 웹 애플리케이션의 요구사항과 잘 어우러지기 때문입니다.

 

하지만 이러한 범주에서 벗어난 웹 애플리케이션이라면 반드시 Node.js가 정답이 될 수 없습니다. I/O작업이 많지 않고 강도높은 CPU 연산이 요구된다면 한개의 Thread를 사용하는 Node.js는 급격한 성능 저하가 야기됩니다.

 

Spring WebFlux의 등장

(Java 진영은 언제나 그래왔듯이 정답을 찾을 것입니다.)

 

Spring WebFlux는 Spring 5에서 도입되었습니다. Spring WebFlux는 Node.js와 유사하게 완전한 비동기-논블러킹 방식의 I/O 작업이 가능하고, 이를 제어하기 위한 Event Loop를 두었습니다. 다른 점이라면 Spring WebFlux는 Single-Thread 기반이 아닌 Multi-Thread 방식입니다. 다만 Spring MVC처럼 각 요청에 하나의 Thread가 대응 되지 않고 다수의 요청을 처리하는 구조입니다.

 

Java진영에서도 비동기-논블러킹 방식의 장점을 취하기 위해서 Node.js를 고려하지 않고 Spring 만으로도 개발이 가능하게 된 것입니다. 

 

더 공부해볼만한 키워드

  • Event-Queue
  • Event-Loop
  • Event-Driven Programming
  • Reactive Programming

참고

반응형
댓글
  • 프로필사진 dd nodejs는 싱글쓰레드 코드 및 이벤트루프를 통해서 threadpool로 콜백작업 전달해서 멀티 쓰레딩 작업을 하지 않나요?
    단지 씽글쓰레드라 표현하는게 노드에서 코드작성을 할때 구조적으로 비동기로 전달해야하는부분이라서 무거운 동기코드를 작성하면 이벤트루프돌아가는것도 문제생겨서 그런거 아닌가요?
    2020.10.27 08:57
  • 프로필사진 사용자 siyoon210 네 말씀하신것처럼 Node.js도 실질적으로는 멀티쓰레딩으로 작업을 진행하는데요. 다만 요청을 다루는 메인 쓰레드는 단 하나의 씽글쓰레드라서 위와 같이 표현했습니다. 2020.10.28 08:26 신고
  • 프로필사진 최용진 Single Thread가 Node.js가 아닌 Javascript의 특징이라고 말씀하신 것과 정확히 같은 이유도 비동기의 장점도 단지 Node.js의 장점이 아닌 Javascript의 특징에서 오는 점이 많습니다. Javascript는 단순히 Web Framework 뿐만 아닌 모든 I/O 대부분의 API가 비동기로 설계되어 처음 배울 때의 패러다임 시프트의 허들이 있을 뿐 비동기의 장점을 충분히 활용할 수 있는 언어 구조가 되어 있습니다. 기반 API 뿐만이 아니라 저는 실질적인 Javascript의 장점을 Promise/Async/Awiat와 같은 언어 구조에서 찾고 있습니다. 이는 Java가 아무리 I/O API를 비동기화 한다고 해도 절대로 Javascript를 따라갈 수 없는 점이라고 생각합니다. Javascript 조차도 Promise/Async/Await 없이는 매우 복잡한 지원 라이브러리 없이는 제대로된 비동기 코드를 작성하기 어렵고 Call Back 지옥에 빠지기 쉬었으니까요. 각각의 랭귀지 별로 장단점은 분명히 있습니다. Node.js의 경우 만일 HTTP 프로토콜이 기존의 HTTP1.1/HTTP2 외에 만약 HTTP3라는 새로운 프로토콜 스택이 등장한다고 가정하면 CPP 등의 다른 Native 언어로 작성된 잘 짜여진 기반 라이브러리 없이는 Node.js만으로는 절대 기능을 구현할 수 없습니다. Java라면 순수 Java 만으로도 해당 기능을 새롭게 구현할 수 있겠지요. 다만 Java가 Javascript 언어가 고유로 가지고 있는 비동기 관련 Feature들을 언어 상에서 지원해 주지 않는다면 개발 용이성 측면에서는 적어도 Java가 Node.js 상대로 비동기 관련 개발은 불리한 점이 많이 있을 것으로 생각됩니다. 2020.11.09 12:47
  • 프로필사진 사용자 siyoon210 Promise/Async/Await을 기반으로한 언어 구조적 장점! 말씀을 듣고보니 납득이 됩니다. 부족한 글에 좋은 의견 감사합니다. :) 2020.11.09 12:53 신고
  • 프로필사진 자바 16 자바 17에서는 fiber 가 들어가는데
    코틀린의 코루틴 개념을 JVM차원에서 지원하게 된다고 합니다.

    spring 의 webflux가 작성하기 불편한점이 있지만 fiber 와 합쳐지면 나중에는
    편하게 되겠네요
    2020.11.22 16:26
  • 프로필사진 지나가는나그네 노드 싱글스레드 쪽 그림 누가봐도 잘못 그리신듯여.. 이거보고 주니어들이 면접봤다간 다 광탈할듯 2021.02.07 10:34
  • 프로필사진 사용자 siyoon210 혹시 어떤부분이 잘못되었는지 알려주실수 있을까요?

    이벤트큐와 이벤트루프에 대한 설명이 부족하긴 합니다만 메타포로써 본다면 전체적인 흐름과 맞다고 생각하는데요. 알고계신 오류를 알려주신다면 감사하겠습니다.
    2021.02.08 01:01 신고
  • 프로필사진 devMarco js 진영에서도 싱글 쓰레드 문제를 극복하고자 pm2가 등장을 했죠~~ 검토해보시면 좋을 거 같네용..
    도커를 사용하는 것도 방법이겠고요.
    2021.06.16 15:03 신고
댓글쓰기 폼