본문 바로가기

서론

 

  최근 면접에서 `Java`와 `Node.js`를 이용해서 백엔드 개발을 할때 어떤 차이가 있냐는 질문을 받았다. 이 질문에 나는 자바에서 스프링을 사용하는 경우 요청 하나당 하나의 스레드가 생성되고 Node.js는 이벤트 루프라고 불리는 싱글 스레드 하나가 모든 요청을 다 받고 I/O작업의 경우 비동기 방식으로 처리를 던져놓고 다른 일을 하고 있다가 I/O작업이 완료되면 이벤트 방식으로 요청이 완료됨을 알리는 방식으로 클라이언트에게 응답한다고 답했다.

 

  Java의 Spring을 이용하는경우와 Node.js를 사용하는경우를 좀 더 자세히 비교하기 위해서 이 글을 작성하였다.

 

 

 

전통적인 웹애플리케이션 요청 처리

 

 

  spring webflux와 같은 차세대 기술이 아닌 spring mvc를 사용하여서 웹애플리케이션을 개발하였다면 위의 그림과 같이 하나의 요청당 하나의 스레드가 생성되고 이에 해당 스레드가 요청을 처리한 후 응답을 하는 방식이다.

 

  만약 서버 메모리가 8 GB 용량을 가지고 있고 하나의 스레드가 2 MB 크기를 가진다고 가정해보자. 즉, 하나의 요청에 2 MB가 소모되는데 이는 동시에 최대 4000개의 요청을 핸들링할 수 있음을 의미한다. 또한, 스레드간에 문맥교환이 발생하는데 문맥교환으로 발생하는 자원소모 역시 적은편은 아니다.

 

 

Node.js 웹애플리케이션 요청 처리

 

  

 

  Node.js는 웹요청을 어떻게 처리할까? 먼저 Node.js에서 일반적으로 잘못 알려진 사실을 바로잡고 넘어가자. Node.js는 싱글스레드만으로 요청을 처리하는것이 아니라 이벤트 루프가 싱글스레드 이고 내부적인 아키텍쳐를 살펴보면 C++로 작성된 프로젝트인 libuv에 스레드풀이 존재한다. 즉, 싱글스레드로만 모든 작업을 하는것이 아니다.

 

 

 

  클라이언트 하나당 한개의 스레드가 생성되는 전통적인 방식과 달리 모든 클라이언트의 요청은 `이벤트루프(싱글스레드)`로 들어가게 된다. 이벤트 루프에서는 모든 요청을 비동기 방식으로 스레드 풀에 존재하는 스레드에게 던져놓고 다른 작업을 계속해서 처리한다. I/O작업을 완료한 워커스레드는 작업이 완료되었다는 이벤트를 발생시키고 이벤트 루프가 이를 응답해준다.

 

 V8엔진의 메모리는 기본적으로 32비트 에서는 512MB로 설정되어 있고 64비트는 1.4GB 값으로 설정되어 있다. 전통적인 웹애플리케이션과 달리 동시에 최대 10,000개의 요청을 처리할 수 있도록 설계되어있다.

 

 

언제 어떤 기술을 사용하는게 유리할까?

기술을 선택할때는 확실한 이유가 있어야 한다. 유형별로 어떤 기술을 사용하는게 좋은지 알아보자

 

 

Cpu Intensive 

CPU Intensive한 작업이 많은경우 절대로 Node.js를 선택하면 안된다. I/O작업이 아니라 CPU를 많이 사용하도록 코드가 작성된 함수가 있는데 어떤 요청이 들어와서 이 함수를 사용한다고 가정해보자. 해당 코드는 libuv에 있는 스레드풀로 던져져서 요청을 비동기방식으로 처리하지않고 이벤트루프 자체에서 blocking당하고 작업이 끝날때 까지 다른 요청들은 계속해서 쌓이게 되면서 성능이 저하된다. 이런 경우에는 spring mvc를 선택하는것이 더 좋다.

 

 

Concurrency

 

 

채팅서비스의 경우 동시에 엄청난 클라이언트의 요청이 발생할 수 있다. 일반적인 채팅서비스에는 단순하게 텍스트 메시지만 주고 받는데 여기서 Node.js를 사용하게 되면 유리하다.

 

 

Object DB의 API 서버

반면, mongoDB와 같은 JSON기반 DB를 사용하는경우에 Java를 선택하면 JSON데이터를 읽어오고 쓸때 JSON 변환과정이 생기게 된다. 반면 Node.js를 사용하게되면 JSON을 별도의 변환없이 바로 사용할 수 있어서 훨씬 유리하다.

 

 

정리

 

  • 스프링 webflux를 사용하면 적은 리소스로 많은 트래픽을 처리할 수 있다.
  • 기술의 장단점을 알고 제대로 사용하자

 

 

 

Spring WebFlux는 어떻게 적은 리소스로 많은 트래픽을 감당할까?

위 그림은 DZone 게시글 중 하나인 Spring WebFlux를 이용한 Boot2와 Spring MVC를 이용한 Boot1을 비교한 그래프이다. 해당 그래프에서는 두 가지 특징을 볼 수 있다. 첫 번째로는 유저가 적을 때에는 성능에..

alwayspr.tistory.com

 

 

 

참고

 

 

How, in general, does Node.js handle 10,000 concurrent requests?

I understand that Node.js uses a single-thread and an event loop to process requests only processing one at a time (which is non-blocking). But still, how does that work, lets say 10,000 concurrent

stackoverflow.com

 

 

Is Node.js Really Single-Threaded?

A tutorial on multi-threading, multi-processing, threads, processes, thread pools, and more

medium.com

 

 

single thread인 Node.js에서 thread 생성하기 1 - worker_thread 모듈

서론 Node.js는 싱글 스레드 이벤트 루프를 사용한다고 알려져있습니다. 따라서 Node.js는 싱글 스레드(?)이다. 라고 잘못 아시는 분들도 종종 있구요. 하지만 Node.js는 이벤트 루프가 싱글 스레드에��

psyhm.tistory.com

 

 

Node.js 최적화, 메모리관리를 위한 flag

Node.js를 쓰다보면 메모리를 점점 잡아먹는 현상을 발견할 수 있다. 이것은 굉장히 일반적인 현상이고, Node.js에서 쓰는 V8엔진은 기본으로 1.4GB 메모리를 한계로 잡아놓고(기본적으로 64비트는 1.4G

blog.canapio.com

 

댓글