서버 프로그램을 제작하는 프레임워크는 다양합니다. 프로그램 언어가 다양한 만큼 많은 종류의 프레임워크가 존재합니다. 각자 손에 익은 언어가 있지만, 사용하는 용도에 따라 사용하는 서버 프로그램 프레임워크도 달라집니다. Node.js로 서버 작업을 하다 갑자기 궁금해졌습니다. 전 세계적으로 가장 보편화 되어 있는 Spring Boot와 Node.js의 expresss는 어떤 차이점이 있을까요?
Spring Boot 🌏️
JAVA 로 구성된 서버 프레임워크입니다. 대한민국은 JAVA 공화국이고, 아직까지도 많은 분야에서 사용되는 언어입니다. JAVA 계열에서는 Spring Boot를 사용해 금방 서버 애플리케이션을 만들 수 있습니다. 개발하는데 필요한 대부분의 라이브러리들이 이미 spring boot에 들어있습니다.
예를 들어 데이터베이스도 JPA를 통해 손쉽게 관리할 수 있고, 라이브러리들의 버전 관리 문제도 쉽게 관리할 수 있습니다. 또한 JAVA Virtual Machine(JVM)으로 작동하기 때문에 어떤 실행 환경에서도 동작할 수 있다는 장점을 가지고 있습니다.
Node.js와 가장 큰 차이점이라고 한다면 GC(Garbage Collection) 기능을 제공한다는 점입니다. 개발자가 메모리에 직접 접근하여 alloc()을 해주지 않아도 자동으로 메모리 상 쓰레기를 정리해줍니다.
두번째 차이점은 Multi Threading으로 작동하는 프로그램을 만들어냅니다. 여러개의 스레드를 동시에 실행하기 때문에 메모리를 많이 사용하지만 불필요한 메모리를 바로 GC가 처리해주기 때문에 안정적인 환경에서 서버 프로그램을 돌릴 수 있습니다.
로직 자체가 동기화 되어 있어 앞에 로직이 완료되어야 뒤의 로직이 작동하는 구조입니다. 이 때문에 CPU 연산이 많은 작업의 경우 높은 퍼포먼스를 보여줍니다. 작업 단위를 여러개의 스레드가 함께 처리하니깐요. 하지만 서버 애플리케인 특성상 단순한 대규모 I/O 트래픽이 들어오는 경우 성능은 급격하게 떨어집니다. 불필요한 컨텍스트 스위칭이 발생합니다.
또한 Spring Boot는 TypeSafe 합니다. JAVA를 기반으로 한 프레임워크다 보니 컴파일이 우선되어야 합니다. 숫자를 담는 변수로 선언된 곳에 문자열을 넣으면 TypeError가 발생합니다. 너무 당연하다고 생각하실 수 있지만 Javascript에서는 이게 가능해져 버려 TypeSafe하지 못합니다. Typescript가 나온 이유입니다.
마지막으로 Spring Boot는 boilerplate 코드가 많습니다. 대표적으로 setter, getter 같은 메소드를 개발자가 직접 만들어 사용해야 하지만 spring boot에서는 자동으로 생성해줍니다. 이런 기초 작업을 하다 타이핑이 미스나는 경우도 있고, 시간도 많이 잡아먹기 때문에 효율적인 개발이 가능해집니다.
❓️ 보일러 플레이트(boiler plate)란?
보일러의 기초 골격이 되는 통을 찍어는 플레이트를 의미합니다. 프로그램의 영역으로 이 단어를 가져온 이유는 항상 사용하지만 매번 사용시 코드를 작성할 필요없이 자동으로 생성한 코드를 업그레이드 한다는 의미를 가지고 있습니다.
Node.js express 🛰️
Javascript 언어를 사용하는 서버 애플리케이션 프레임워크입니다. 기존에는 프론트에서만 HTML, CSS를 조작하는 기능을 담당하던 언어였지만 Google의 V8엔진을 탑재한 Node.js가 출시되면서 서버 영역에서도 Javascript를 사용할 수 있게 되었습니다. 프로그램 언어 중 가장 쉽게 접근하기 좋은 언어 중 하나입니다.(다른 하나는 Python)
⁉️ Node.js 는 서버 프로그램 일까요?
엄밀히 말하면 Node.js는 서버 애플리케이션 프레임워크가 아닙니다. Javascript라는 언어가 동작할 수 있는 환경을 기존 웹 브라우저에서 로컬 환경으로 가져온 것 뿐입니다. Node.js === 서버 프로그램이라는 말은 맞지 않는 말입니다. Node.js 환경에서 서버 뿐만 아니라 웹 크롤링, 게임 제작, 데스크탑 애플리케이션 등 다양한 프로그램을 제작할 수 있습니다.
Node.js Express는 싱글 스레드만을 사용합니다. 여러 작업을 수행하기 위해서는 비동기 처리를 해주어야 합니다. ES6에서는 async ~ await 기능이 추가되면서 동기 함수처럼 작성하되 기능은 비동기로 작동할 수 있게 되었습니다.
싱글 스레드로 돌아가기 때문에 프레임워크 자체가 가볍습니다. 메모리를 많이 사용하지 않고, API 기능을 수행할 수 있습니다. 다른 프레임워크에 비해 수행속도가 현저하게 높습니다. 다만 CPU를 많이 사용하는 작업의 경우 싱글 스레드의 한계를 명확하게 보여줍니다.
boilerplate 코드로 제공되는 파트가 별로 없습니다. 따라서 개발자의 코딩 스타일에 따라 천차만별의 코드가 생성됩니다. 자동완성 기능도 타 프레임워크에 비해 부족합니다. convention을 하는 과정에서 많은 충돌이 발생할 수 있습니다.
크리티컬한 문제는 TypeSafe하지 못하다는 점입니다. 규모가 작은 애플리케이션을 만들 때는 에러 핸들링이 가능하지만 규모가 커지면 커질 수록 TypeSafe하지 못한 성격 탓에 서버가 돌아가다 멈출 수 있는 가능성을 완전히 배제할 수 없습니다. Javasciprt는 컴파일을 하지 않고 서버 실행은 빠르지만 안정성 측면에서 부족한 부분입니다.
Spring Boot VS Node Express 성능 비교
위에서 살펴본 것과 같이 JAVA 진영의 Spring Boot와 Javascript 진영의 Node.js 명확한 차이를 보여주고 있습니다. 과연 성능 차이는 얼마나 날까요?
RestfulAPI의 특징을 살펴보면
- 여러개의 Request을 동시에 처리해야 합니다.
- I/O 작업이 빈번합니다.
- 단순한 작업 ( CPU 작업량이 작습니다.)
이러한 서버 애플리케이션의 태생으로 볼 때 Node.js가 높은 성능을 보여줍니다. Spring Boot의 경우 사용자가 요청한 Request 하나하나마다 스레드가 생성되기 때문에 응답이 올 때 까지 스레드가 기다릴 수 밖에 없고 동시 접속이 늘어날 수록 스레드 갯수가 늘어나고, context switching이 빈번하게 발생하여 결국 성능 저하로 이어집니다.
반면 Node.js 환경에서는 빈번한 I/O를 사용하는 경우 단 1개의 스레드만 운용하고, 작업이 오래 걸리는 요청은 Event Loop로 처리하면서 빠르게 응답이 가능합니다. 자원을 낭비하지 않고 효율적으로 사용자의 Request를 처리할 수 있습니다.
아래그림은 Amir Muminovic에서 Node.js와 Java의 성능을 비교한 것입니다. IO 속도나 메모리 사용량, 시작 시간 모두 Node.js가 압도적으로 높은 퍼포먼스를 보여줍니다.
하지만 CPU 사용량을 늘리며 두 언어의 성능을 비교해보면 CPU 사용량이 늘어날 수록 Node.js 의 성능은 급격히 떨어지게 됩니다. 싱글 스레드의 한계점이 명확하게 보입니다.
🚀️ 도움이 되셨나면 구독과 좋아요 부탁드립니다 :)
'Programming' 카테고리의 다른 글
Django Admin superuser 계정 생성 비밀번호 찾기 💡️ (0) | 2022.10.01 |
---|---|
프로세스 스레드 차이점 ⁉️ (0) | 2022.10.01 |
Django 프로젝트 시작하는 방법 💡️ (0) | 2022.10.01 |
[회고록] 코드스테이츠 블록체인 파이널 프로젝트 완수 후기 (2) | 2022.09.30 |
MongoDB Atlas 백업 하는 방법 (mongodump mongorestore) (0) | 2022.09.29 |
댓글