SW

Spring Boot와 Node 비교

crossfit_wod 2024. 11. 14. 12:07

Node

Node는 Javascript로 만들 수 있는 Server application입니다. Non-Blocking I/O를 처리하는 데 최적화 되어있습니다.

Node의 구동 방식

즉, 다른 작업이 처리가 되는 동안 다른 작업을 하는 것입니다. 따라서 짧은 시간에 여러 작업을 처리할 수 있어 효율적입니다.

 

따라서 1번에 N개의 요청이 들어와도 Event Loop에 의해서 비동기 처리가 됩니다. 요청을 보내고 가만히 있는 동기 방식보다 매우 효율적입니다.(쉽게 말하면 스레드가 1개이기 때문에 계속 일을 시키는 것입니다.)

  • Node : 스레드 1개, 빠르게 작업 처리, 비동기 형식
  • Spring : 스레드 여러개, 동기 형식 (물론 WebFlux 사용하면 비동기 가능)

Memory

또한 스레드가 1개여서 메모리를 많이 잡아 먹지 않습니다.

  • Node : 아무것도 하지 않는 경우 25MB 메모리 소요
  • Spring : 아무것도 하지 않는 경우 400MB 메모리 소요

그래서 MSA구조로 바꾸었을 때 최소 6 ~ 7개의 서버가 필요한데 이 경우 Spring은 3GB나 필요하지만, Node의 경우 200MB만 있으면 충분합니다.

Build

또한 Build의 속도가 매우 빠릅니다. Build가 빠르다는 의미는 트래픽이 많이 몰리는 경우, 큰 의미를 가지게 됩니다. 서버의 수를 유동적으로 바꾸고 빠르게 Build해서 대응이 가능하다는 것입니다. 즉, 즉각적인 빠른 대응이 가능하다는 것입니다.

CPU 연산이 적은 경우 처리량, Build 시간, Memory모든 부분에서 Node + TypeScript가 우세합니다.
CPU 연산이 큰 경우 Java, Spring이 우세하다.

정리

노드의 빠른 서버 가동 시간과 적은 Memory 사용량 등 Node의 가벼움은 장점을 발휘합니다. 결론은 CPU연산이 많을 경우 Spring이 우세하며 CPU 연산이 적은 경우 Node가 유리합니다.

Node의 큰 단점

컴파일 단에서 Type 에러를 해결할 수 있다.

 

하지만 단점으로는 Type Safe하지 못한 큰 문제가 있습니다. 하지만 TypeScript이 등장함으로서 어느정도 해결이 되었습니다.(Java를 공부한 사람에게는 많이 편할 것입니다.)


비교

Spring Boot

스프링 부트는 Type을 정하기 때문에 Type Safe합니다. 따라서 Runtime이 아닌 Compile시에 문제를 찾고 빠르게 해결할 수 있습니다. (확실히 Node의 경우 TypeScript를 사용한다고 해도 Java만큼의 Compile은 못 할 것라고 생각이 듭니다.)

 

또한 Spring Boot의 경우 Java를 사용하기 때문에 Multi Thread로 동작을 합니다. 즉 오래 걸리는 요청이면 바로 새로운 스레드를 생성해 다른 요청을 받아서 처리하는 장점이 있습니다.

 

그리고 가장 생태계가 많이 발전해 있습니다. 국내 대기업의 경우 대부분 Java Spring을 사용해서 운영하고 있습니다. 따라서 참고할 만한 레퍼런스나 유투브, 문서도 많습니다.

 

반대로 Node의 경우는 Node 생태계가 Java에 비해서 많이 발전하지는 못했습니다.

 

하지만 단점으로는 Build시 오래 걸립니다. 실행을 할 때, JVM과 Garbage Collection 로딩에 의해서 실행이 지연됩니다. 가장 큰 문제는 객체지향을 추구하기 때문에 학습을 하면 할 수록 난이도 측면이 올라가는 것입니다. (이 부분은 큰 장점이자 단점으로 느껴집니다.)

Node vs Spring Boot 결론

spring boot

  • 로딩(Build)가 오래 걸리지만, Runtime이 아닌 실행 초기(Compile)에 빈을 검증하고 등록하는 과정에서 결함을 발견
  • 쉽게 구동, (Embedded Tomcat)IOC, AOP, POJO 등 스프링은 개발자가 비즈니스 로직에만 집중할 수 있도록 함
  • 효율적인 JPA와 편리한 QueryDSL이 프레임워크를 단단하게 뒷받침
  • Spring security, Exception Handler 등 필요한 좋은 기능을 많이 제공
  • 비즈니스 로직에 더 잘 집중

Node

  • 싱글 쓰레드(Single-Thread)이기 때문에 메모리 절약측면에서 효율적
  • 요청을 보내고 가만히 기다리는 동기 방식보다 시간적으로 효율적
  • 코드가 쉽고 간편
  • 처리하는 작업 크기가 작고 요청이 많은 서버에서 효율적
  • 세계적인 대규모 라이브러리 리소스 풀을 사용
  • 여러 요청이 동시에 와도 Event loop에 의해 비동기로 처리
  • 요청이 들어오거나 메소드가 실행되어야 에러를 찾을 수 있는 경우가 많음(즉, Runtime 환경에서 확인할 수 있음)

고민과 해결

현재 새로운 신규 프로젝트를 진행하게 되었습니다. 제가 고려한 것은 4가지 입니다.

 

1. Time to market : 스타트업인 만큼 빠르게 Due date가 있는 기간 동안 개발을 해야한다고 생각했습니다.

2. Feedback, error : 고객들이 원하는 피드백을 필요한 부분은 빠르게 반영해야 한다고 생각 했으면, 에러가 발생했을 경우 빠르게 대응해야 한다고 생각했습니다. 이 때 Build의 속도가 빠른 Node가 빛을 본다고 생각했습니다.

3. Fast develop : 현재 저의 수준으로는 Java Spring으로 프로젝트를 만들면 오랜 시간이 걸린다고 판단했습니다. 최대한 객체 지향적으로 코드를 작성하고 싶은 마음이 있기 때문에 여러가지를 생각하면서 작성할 것 같다는 생각을 했습니다.

4. Team: 현재 사내 개발자가 FE 1명 BE1명으로 구성되어 있어서, 만약 Java로 진행을 할 경우 Java 에러에 대해서 물어볼 사수가 없습니다. 하지만 Node와 TypeScript를 사용하면 FE 또한 React와 TypeScript를 사용하기 때문에 궁금한 것과 에러 부분을 물어볼 수 있는 사수가 있습니다.

 

다행히도 Node 진영에서 Nest.js라는 Spring과 비슷한 프레임워크가 나왔습니다. DI, IoC, TypeORM와 같은 개념 그리고 Controller, Service, Module같은 개념이 너무 Spring과 비슷해서 빠르게 배울 수 있었습니다.

NestJS 공식문서
배민의 새로운 표준

참고

 

네이버 개발자가 작성한 블로그