본문 바로가기
IT/Server

[Server] Spring vs Node.js

by kyu-nahc 2024. 10. 2.
반응형

 

Spring / Node.js Framework

대중적으로 사용하는 백엔드 프레임 워크Spring, Node.js 가 있다.

백앤드 개발자 공고를 찾아봐도 Spring 혹은 Node.js 서버 개발 경험을 중요시 여긴다.

따라서 두 가지 Framework의 차이점을 이해하고 상황에 맞는 프레임워크를 선택할 필요가 있다.

 

Node.js 

먼저 Node.js의 정의를 살펴보면 다음과 같다.

Google Chrome의 V8 Javascript 엔진으로 빌드된 Javascript 런타임

 

쉽게 말하자면 JavaScript를 이용하여 서버를 만들어 줄 수 있는 툴이다.

이 전의 Javascript는 스크립트 언어이기 때문에, 

특정 웹 브라우저(익스플로어, 크롬, 사파리) 안에서만 동작하였다. 
즉, Javascript는 독립적으로 사용될 수 없었다.
Server-Client로 동작하는 웹사이트 / 앱에서 이 전에는

Javascript로 웹에서 표시되는 Client만 구현이 가능하였다.

 

하지만 Node.js의 등장으로 Javascript 런타임 환경이 만들어져,

웹 브라우저에서 독립되어 터미널등에서 Javascript를 실행시킬 수 있게 되었다.
즉, 웹 브라우저와 무관한 Javascript만으로 이루어진 독립적인 프로그램을 만들 수 있게 되었다.
또한 Server-Client로 동작하는 웹사이트 / 앱에서 Server 부분에서도

Javascript를 사용할 수 있게 되었다. Node.js의 특징을 살펴보면 다음과 같다.

 

Node.js 특징

Single Thread

Node.js는 하나의 프로세스 하나의 스레드를 통해 코드가 실행된다.

스레드가 I/O Request를 받으면, 다른 처리로 요청을 보내고 다른 작업을 처리한다.

그 후 요청하였던 작업이 끝나면 해당 이벤트를 받아 나머지 응답을 처리한다.
즉, 동시에 여러 Request가 오더라도, 

해당 I/O를 기다리지 않아도 되기 때문에 서버의 부하가 줄어들게 된다.
또한 싱글 스레드를 사용하기 때문에 멀티 스레드에 비해 메모리 측면에서 효율적이다.
이때 이벤트 루프가 싱글 스레드로 처리하는 것이고, 

내부적인 아키텍처를 살펴보면 C++로 작성된 libuv에 스레드 풀이 존재하고 있다. 

즉 Node.js는 I/O Request시 스레드 풀에 요청을 던지는 것이다.

Event Loop

libuv라는 이벤트 기반(Event-Driven),

논 블로킹(Non-Blocking) I/O 모델을 구현한 라이브러리를 사용한다.
이벤트 기반은 이벤트가 발생할 때 지정해 둔 작업을 수행하는 방식으로, 

이벤트가 발생하면 Node.js는 지정해 둔 콜백함수를 실행하고, 

이벤트가 끝나면 Node.js는 다음 이벤트 발생 시까지 기다린다.
이때 이벤트 루프(Event Loop)가 여러 이벤트가 발생 시, 

콜백함수의 호출 순서를 판단하고 이벤트가 종료될 때까지 작업을 반복한다.

 

Non-Blocking I/O

Node.js는 논 블로킹 I/O의 특성을 활용하여 오래 걸리는 작업을 효율적으로 처리한다.
블로킹은 특정 작업이 수행되는 동안 특정 작업이 제한되는 것인데 

Node.js는 비동기 방식을 통하여 블로킹이 되지 않게끔 한다.
이때 비동기란 어떠한 작업이 끝날 때까지 기다리지 않고 다른 작업을 동시에 진행하는 것이다.

Node.js는 비동기 방식으로 동작하므로,

함수 호출이 발생하면 요청을 비동기적으로 처리하여 동시에 여러 요청을 처리할 수 있다.

즉 요청이 완료된 순서와 상관없이, 완료된 요청부터 순차적으로 처리된다.

 

위의 특징들을 정리하면

Node.js는 싱글 스레드의 이벤트 루프 기반의 논 블로킹 I/O를 모델로,

I/O 요청이 많은 서버에 효율적이다. 하지만 싱글스레드를 사용하기 때문에, 

CPU 연산이 많거나 복잡한 프로그램에는 적합하지 못하게 된다. 

또한 콜백 지옥이라는 문제가 발생할 수 있고, 동기화 문제도 발생할 수 있다.

즉 채팅 혹은 특정 값의 변화와 같은 

많은 양의 작은 데이터를 주고받는 프로그램에 Node.js는 효율적이다.

 

Spring

다음으로 Spring의 정의부터 살펴보면 다음과 같다.

오픈소스 기반의 Java 웹 애플리케이션을 개발할 수 있는 Framework 
즉, Java의 기술들을 더 쉽게 사용 가능하도록 Java에서 자주 사용하는 기능들의 집합

 

Spring Boot는 위의 Spring을 더 쉽게 사용하여 

상용화 가능한 애플리케이션을 만들 수 있도록 돕는 도구이다. 

Spring은 초기에 세팅해야 할 것이 많아, 개발자들에게 진입장벽이 높고 할애되는 시간이 많은데,

이러한 문제를 해결하고자 등장한 Framework가 Spring Boot이다.

Spring 특징

Spring은 기본적으로 웹 프로그래밍 개발의 표준인 MVC 패턴을 사용한다.

Spring은 "경량 컨테이너"로서 Java 객체와 라이브러리등을 직접 관리해 주며, 

WAS(ex 톰캣)이 내장되어 있어 애플리케이션을 구동할 수 있도록 한다.
Java 객체의 생성 및 소멸과 같은 생명주기(Life Cycle)를 관리하고, 

필요한 객체는 Spring 컨테이너에서 사용하는 등 Java 객체를 직접 Spring안에서 관리한다.
Spring은 복잡한 트랜잭션을 어노테이션 혹은 xml을 통해 설정하여 

개발자가 매번 상황에 맞는 코드를 작성하지 않아도 된다.
이제 Spring에서의 몇 가지 주요 특징을 살펴보면 다음과 같다.

 

IOC ( Inversion Of Control )

IOC는 제어의 역전을 뜻하며, 일반적인 자바 프로그램에서

각 객체를 직접 생성하고 객체의 메서드를 호출하는 등 직접 객체를 생성 및 조작하였다.

이때 IOC란, 이렇게 사용자가 직접 작업을 제어하는 것이 아닌,

Spring에서 의존성 객체를 만들어주고 필요한 곳에 넣어주어

기존에 사용자가 가졌던 제어권을 다른 주체에게 넘겨주는 것을 의미한다.

DI ( Dependency Injection )

DI는 의존성 주입을 뜻하며, 필요로 하는 객체를 자신에게 직접 생성하는 것이 아닌,

필요로 하는 객체를 외부(Spring)에서 생성하여 사용하려는 객체에 주입시켜 주는 것을 의미한다.

직접 객체를 생성하는 경우 의존성이 높지만,

DI와 같이 외부에서 객체를 주입하게 되면 의존성을 줄일 수 있게 된다.

 

POJO ( Plain Old Java Object )

POJO란, 말 그대로 평범하고 오래된 자바 객체를 의미한다.

이는 Spring에서 객체 간의 관계를 구성할 때, 별도의 API를 사용하지 않고

Java 코드를 이용하여 객체를 구성할 수 있음을 의미한다.

이를 통해 개발자가 코드를 작성할 때

특정 라이브러리나 컨테이너의 기술에 종속되지 않을 수 있다.

 

AOP ( Aspect Oriented Programming )

AOP란, 개발자가 비즈니스 로직에만 집중할 수 있도록

반드시 처리가 필요한 부분을 모듈로 분리하는 프로그래밍의 패러다임을 의미한다.

즉 AOP는 관점(Aspect) 지향 프로그래밍으로,

관점을 기준으로 다양한 기능을 분리하여 보는 프로그래밍이다.

관점(Aspect)이란, 부가 기능과 그 적용처를 정의하고 합쳐서 모듈로 만든 것이다.

위의 Spring에 대한 특징들은 아래 포스팅을 통해 자세히 살펴볼 수 있다.

 

[Spring boot] AOP (Aspect Oriented Programming)

AOP ( Aspect Oriented Programming )AOP는 관점(Aspect) 지향 프로그래밍으로, 관점을 기준으로 다양한 기능을 분리하여 보는 프로그래밍이다. 관점(Aspect)이란, 부가 기능과 그 적용처를 정의하고 합쳐서

kyu-nahc.tistory.com

 

[Spring boot] POJO (Plain Old Java Object)

POJO (Plain Old Java Object)위 이미지는 Spring 삼각형이라는 이미지로 Spring의 핵심 개념들을 표현하고 있다.POJO는 IoC / DI, AOP, PSA를 통해서 달성할 수 있다는 것을 의미한다. POJO란 Plain Old Java Object의 약

kyu-nahc.tistory.com

 

[Spring boot] Spring DI와 생성자 주입의 이유

Dependency Injection란? (의존관계 주입)DI는 Spring에만 적용되는 것이 아닌 모든 객체지향 프로그래밍에서는 사용되는 개념이다.먼저 의존성이란 객체를 생성 및 사용함에 있어서 의존 관계를 가지

kyu-nahc.tistory.com

위의 특징들을 정리하면 스프링 프레임워크는 기본적으로 Java 언어와 JVM 기반으로 동작하며,

Java의 스레드 기능을 활용하여 멀티 스레드 방식으로 동작한다.

스프링은 요청마다 새로운 스레드를 생성하여 처리하며,

각각의 요청이 독립적으로 처리되기 때문에  안정적이고 예측 가능한 방식으로 동작한다.

하지만 스레드의 생성과 관리에 대한 오버헤드가 발생할 수 있고, 

스레드의 동기화 문제도 발생할 수 있다.

 

Spring vs Node.js

위의 Spring과 Node.js의 특징들을 정리하였는데,

결국 어떤 상황에 무슨 Framework를 사용하는 것이 좋을까?

아래 그림을 통해 먼저 두 개의 프레임워크를 비교해 보면 다음과 같다.

Node.js vs Spring boot

 

처리량, 실행시간, 메모리 사용량 모든 부분에서 Node.js가 우세하다.

물론 그림의 그래프는 CPU 사용량이 적은 간단한 I/O 요청의 경우이다.

Cpu Operation

 

위의 그림은 동일한 처리를 하는데 걸리는 수행 시간을 비교한 그래프이다.

CPU를 사용하는 연산이 많아질수록 Node.js의 처리 수행 시간은 급격히 증가한다.

즉, CPU 연산이 많을수록 Spring이 유리하고 간단한 I/O가 많을수록 Node.js 가 유리하다.

추가적으로 외부 API에 작업을 요청하는 부분이 많으면 Node.js가 유리하다고 볼 수 있다. 

스프링은 동기 방식이기 때문에 요청을 보내고 대기하기 때문이다.

따라서 정리해 보면 Node.js가 성능적 이점을 내는 상황은 아래와 같다.

  1. 다중처리를 동시에 처리하도록 요구
  2. 많은 I/O작업을 수행
  3. 단순한 CPU 작업만을 진행
  4. 외부 API 작업에 대한 요청

따라서 Node.js비동기 I/O 처리 능력확장성 등의 장점으로 인해 

대용량의 요청을 빠르게 처리하고, I/O 처리가 많은 애플리케이션에서 사용하기 좋다.

 

스프링 프레임워크IOC, DI, POJO, AOP의 특징들을 통해

개발자가 비즈니스 로직에 더욱 집중할 수 있도록 해주고

Spring Security, JPA 등 유용한 핵심 기능들을 많이 제공해 준다.

따라서 스프링 프레임워크가 효율적인 곳은
안정성, 확장성, 보안성, 통합성등의 장점으로 인해 

안정성과 예측 가능성이 중요한 애플리케이션에서 사용하기 좋다고 할 수 있다.

 

위의 Node.js / Spring의 특징들로 인해,

스타트업은 기업 구조 특성상 새로운 플랫폼을 구축하는데 거리낌이 없기 때문에

비교적 최신 기술을 사용하기에 좋은 상황이고 그 선택지로 Node.js를 많이 사용한다.

더군다나 최근에 잘 사용하는 NestJS자바 스프링 방식을 그대로 사용하기에

스프링에만 존재하던 장점을 이제는 NodeJS에서도 누릴 수 있게 된 상황이다.

 

반면 대기업에서는 그동안 자바로 쌓아 올린 견고한 시스템이 존재하고

이를 다른 프레임워크 내지 프로그래밍 언어로 교체한다는 것은

사실상 불가능한 일이라 때문에 계속해서 자바 개발자를 더 선호한다고 볼 수 있다.

 

 

 

참고자료

https://cdragon.tistory.com/entry/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%94%84%EB%A7%81JavaSpring%EC%99%80-Nodejs-%EB%8C%80%EA%B8%B0%EC%97%85%EC%9D%80-%EC%9E%90%EB%B0%94-%EC%8A%A4%ED%83%80%ED%8A%B8%EC%97%85%EC%9D%80-Nodejs-Spring%EA%B3%BC-Nodejs-%EC%A4%91%EC%97%90-%EA%B3%A0%EB%AF%BC%EC%9D%B4%EC%8B%A0%EA%B0%80%EC%9A%94

https://codenme.tistory.com/80

 

반응형

loading