한국에서 가장 인기 있는 웹 프레임워크는 단연 자바를 이용한 Spring입니다. 저도 처음 개발을 배울 때는 Spring을 활용했었는데요. 확실히 Spring은 엔터프라이즈급 애플리케이션을 개발하기에 굉장히 좋고 관련 레퍼런스 자료도 많기 때문에 추천될 만한 프레임워크라고 생각합니다. 하지만 저는 Spring을 활용할 때는 항상 세팅 시간이나 개발 과정이 너무 오래 걸려 불편함을 느꼈습니다. 일례로 Spring에서는 의존성 주입을 위해 직접 pom.xml 혹은 build.gradle을 수정해야 하지만, 파이썬 Django나 자바스크립트(타입스크립트) NestJS는 pip 혹은 npm을 이용해 간단하게 의존성을 관리할 수 있었습니다. 또한 빌드 시간이 꽤 길다는 것도 큰 단점이라고 생각합니다.
이런 여러 이유로 다른 웹 프레임워크를 알아보던 중 NestJS, Django 등위에 대해 알게 되었습니다. NestJS는 굉장히 빠른 속도로 유명한 Chrome V8 엔진을 활용한 Node.js 기반 프레임워크인데요. React에서 사용하는 자바스크립트(타입스크립트)를 그대로 사용해 풀스택을 개발하는데 굉장히 편리하다는 장점이 너무 좋아 보여 몇 번 사용해 보기 시작했고, 이용해 보자마자 생각보다 이용하기도 너무 편하고 빠르게 동작해서 너무 좋다고 생각했습니다. 또한 Django도 인스타그램과 스포티파이에서 사용하는 프레임워크라고 하여 몇 번 사용을 해보았습니다. 하지만 이 과정에서 개발을 공부하시는 분들은 한 번쯤 해봤을 고민을 저도 하게 되는데요. '과연 NestJS가 Spring 보다 좋은 걸까?', '그럼 Django 같은 프레임워크는 또 어떨까?' 이런 고민들을 하게 됩니다.
오늘은 제가 개인적으로 조사한 자료를 공유하면서 어떤 프레임워크를 사용할지 혹은 어떤 프레임워크에 대해 공부해 볼지 고민하는 분들을 위해 글을 작성해보려 합니다.
기준 1) 작업의 종류
프레임워크를 선정할 때 고려할 기준 중 하나가 바로 어떤 작업을 주로 처리할 것인지입니다. CPU 집약적인 작업이 많을 수도 있고 단순 I/O 집약적인 작업이 많을 수도 있습니다. 예로 다음과 같은 것들이 있습니다.
- CPU 집약적인 작업
- 복잡한 수학 계산
- 대량의 데이터 처리 및 변환
- 영상 및 이미지 처리
- 딥러닝
- I/O 집약적인 작업
- 데이터베이스 I/O
- 네트워크 요청
- 스트리밍 데이터 처리
- Spring
Spring의 경우 일반적으로 서블릿 컨테이너인 Tomcat 위에서 실행됩니다. Tomcat은 기본적으로 멀티 스레드 환경으로 동작하는데요. 즉, 여러 명의 사용자가 동시에 Spring 서버에 요청을 보낸다면, Tomcat은 스레드 풀에서 각 요청에 대한 별도의 스레드를 할당하여 여러 요청을 병렬로 처리해 동시성 문제를 해결합니다. 결과적으로 CPU 집약적 작업으로 인해 하나의 스레드가 이미 바쁜 상황에도 다른 요청이 들어오면 해당 작업이 끝날 때까지 기다릴 필요 없이 다른 스레드를 이용해 병렬로 처리할 수 있다는 강점이 있습니다.
- NestJS
NestJS의 경우 Node.js 기반으로 동작하고 이는 싱글 스레드 환경을 제공합니다. 즉, 모든 요청을 하나의 스레드가 처리하는 형식인데요. 사실 더 정확하게 표현하자면 모든 요청을 하나의 스레드가 받긴 하지만, 비동기 작업의 경우에는 libuv라는 멀티 스레드로 이동되어 처리되기 때문에 실질적인 작업이 모두 하나의 스레드에서 이루어지는 것은 아닙니다. 하지만 libuv 같은 멀티 스레드 풀은 기본적으로 I/O 작업을 처리하기 위한 용도로 CPU 집약적 작업의 경우는 보통 libuv가 아닌 메인 스레드(싱글 스레드)에서 실행됩니다. 즉, CPU 집약적 작업으로 인해 싱글 스레드가 이미 바쁜 상황이라면 다른 요청이 들어왔을 때 해당 작업이 끝날 때까지 기다려야 한다는 단점이 있습니다.(하지만 노드 10 버전부터는 worker threads와 cluster라는 개념이 추가되어 과거보다 더 효율적으로 CPU 집약적인 작업을 처리할 수 있습니다)
반대로 I/O 바운드 작업에서는 굉장히 좋은 성능을 보인다는 장점이 있습니다. 왜냐하면 비동기 논블로킹 I/O 아키텍처를 사용해서 I/O 작업들을 빠르게 비동기 처리하기 때문입니다. 간단하게 설명하면 위에서 언급한 libuv 멀티 스레드들에 I/O 작업들을 하청을 주어 빠르게 처리하는 구조입니다.
- Django
Django도 GIL(Global Intepretor Lock)으로 인해 멀티 스레드를 지원하지 않아 싱글 스레드로 동작합니다. 그리고 여러 요청을 처리하기 위해 멀티 프로세스로 동작합니다.(싱글 스레드인 Django 프로세스가 여러 개 실행되는 상황) 이때 결국에는 하나의 프로세스에 하나의 스레드로만 실행되기 때문에 CPU 집약적 작업에 효율적이지는 않다는 단점이 있습니다.
하지만 Django는 웹 서버를 따로 설치하지 않아도 테스트가 가능하도록 내장 서버가 탑재되어 있고, 기본적으로 관리자 화면을 구성해 주어 개발자가 별도로 관리 기능을 개발할 필요가 없습니다. 이렇게 빠르고 쉬운 개발이 가능하다는 것이 Django의 큰 강점입니다.
기준 2) MA vs MSA
MA(Monolithic Architecture)로 설계할지 MSA(MicroService Architecture)로 설계할지에 따라 선택할 프레임워크도 변경될 수 있습니다. 예전에는 보통 MA를 사용해 크고 성능이 좋은 서버 하나를 운영하는 것이 일반적이었습니다. 하지만 최근에는 서버를 유동적으로 스케일링할 수 있으며 서비스 간 결합도를 낮춰 장애 격리가 쉬운 MSA를 선호합니다.
Spring과 NestJS를 비교해 봅시다. 위에서 CPU 집약적인 작업들은 싱글 스레드를 사용하는 NestJS의 경우 느리게 처리된다고 했는데요. 하지만 MSA라면 여러 NestJS 서버를 만들 수 있으므로 어느 정도 이런 단점을 무마할 수 있습니다. 또한 MSA 구조에서는 트래픽에 따라 서버를 늘렸다 줄였다를 빠르게 할 수 있어야 MSA의 장점을 확실히 느낄 수 있습니다. 이런 과정에서 NestJS는 Spring에 비해 적은 메모리를 차지하며 서버 가동 시간도 훨씬 빠르기 때문에 더 즉각적이고 유동적인 운영이 가능하다는 장점이 있습니다.
마무리
결과적으로 각 프레임워크의 구조, 작업 종류, 전체적인 아키텍처, 개발 속도 등을 모두 고려해서 현재 상황에 가장 적합한 프레임워크를 선택하는 것이 중요하다고 생각합니다. 저도 아직은 각 프레임워크의 장점과 단점을 몸소 체험한 적은 없습니다. 단순 자료 조사를 통해 "이런 경우에는 이런 프레임워크가 더 좋겠다" 이 정도의 감만 잡은 상태입니다. 이런 부분은 앞으로 여러 개발을 경험해 가면서 보완해야 할 부분일 것 같습니다. 혹시 자신만이 알고 있는 프레임워크별 장단점이 있다면 댓글을 통해 공유해 주시면 정말 감사하겠습니다.
참고한 자료 및 블로그 :
‘Node.js’ VS ‘Java Spring’
저는 네이버 파이낸셜 페이플랫폼에서 개발 업무를 담당하고 있는 김태우 입니다.
medium.com
16년차 개발자가 말하는 Node.js를 선택해야 하는 이유 - 내일배움캠프 블로그
Node.js의 장점은 무엇일까요? 앞으로 취업 전망은 괜찮을까요? 현직 개발자에게 물어봤습니다. | 👨🏻🚀멘토인터뷰, 백엔드 개발
nbcamp.spartacodingclub.kr
파이썬 장고(Django)를 사용하는 이유
파이썬 장고(Django)는 파이썬에서 인기 있는 웹 프레임워크입니다. 파이썬 장고를 왜 사용하는지 이유와 다른 프레임워크와 어떻게 다른지 설명해 보았습니다.
modulabs.co.kr
'백엔드' 카테고리의 다른 글
[ELK] Filebeat 핵심 요약 및 설정법 (0) | 2025.02.08 |
---|---|
npm에서 yarn으로 갈아타기(yarn berry) (0) | 2024.11.07 |
Kafka 카프카에 대한 이해와 간단한 실습 (0) | 2024.11.04 |
MSA 구조 구성의 핵심: 메시지 큐(Message Queue)란? - RabbitMQ, Kafka, Redis (0) | 2024.11.04 |
캐싱 전략을 이용한 백엔드 성능 향상 (0) | 2024.11.02 |