Node.js 란?

Hyeonjeong Jeon·2022년 10월 27일
0
post-thumbnail

기초: 자바스크립트의 특징

우선 자바스크립트와 다른 프로그래밍 언어의 차이점을 알아보자.

  • JavaScript는 Chrome과 Firefox와 같은 브라우저에서 작동하는 프로그래밍 언어이다.
  • 그에 반해 파이썬이나 루비와 같은 일반적인 프로그래밍 언어는 대부분 PC에서 작동한다.

이것이 만드는 차이점은 OS 기능에 액세스를 할 수 있는지의 여부이다.

  • 여기서 "OS의 기능"이란 예를 들어 파일의 읽고 쓰기나, 네트워크 통신 등의 기능을 의미한다.

만약 브라우저에서 실행되는 프로그램이 OS 기능에 액세스할 수 있다면 어떻게 될까?

  • 그렇게 될 경우, 어떤 사이트에 액세스 한 것만으로 마음대로 PC 상의 파일을 읽고 쓰거나 파일을 일부 삭제할 가능성이 생긴다.

따라서 브라우저 상에서 움직이는 JavaScript는 OS의 기능에 액세스하지 않도록 되어 있다.
(but, OS 기능 전부 액세스할 수 없도록 하는 것은 불편하므로 브라우저가 한정적으로 OS의 기능에 액세스를 중개해 주고 있다. 최근에는 카메라나 마이크에 액세스 중개를 해주므로, 브라우저에서 Web 회의가 가능하게 됐다.)

Node.js란?

Node.js 공식 사이트에서는 노드를 다음과 같이 설명하고 있다.

Node.js는 Chrome V8 JavaScript 엔진으로 빌드 된 JavaScript 런타임입니다.

여기서 JavaScript 런타임은 자바스크립트가 구동되는 환경을 말한다.

즉, Node.js는 웹 서버도, 프레임워크도 아닌 Javascript 실행 환경일 뿐이다.
브라우저에 종속적인 자바스크립트를 브라우저 없이 독립적인 환경에서 동작할 수 있도록 해준다.

  • 주로 서버 사이드 애플리케이션 개발에 사용되는 소프트웨어 플랫폼이다.
  • 내장 HTTP 서버 라이브러리를 포함하고 있어 서버 역할을 수행할 수 있으나 Node.js 자체로는 서버가 아니다.
  • libuv를 통해 컴퓨터 내부에 있는 File System 등 System Call 처리도 가능해진다.
    (libuv: Node.js가 사용하는 이벤트 기반, 논 블로킹 I/O 모델을 구현하는 라이브러리)

Node.js의 특징

Node.js는 싱글 스레드의 논 블로킹 I/O 이벤트 기반 비동기 방식으로 작동한다.

  • 싱글 스레드 (Single Thread)
  • 이벤트 기반 (Event-driven)
  • 논블로킹 I/O (Non-Blocking I/O)
  1. 싱글 스레드이기 때문에 비동기 동작이 필요하고, 비동기 동작을 구현하기 위해 이벤트 기반의 동작 방식을 사용한다.
  2. 싱글 스레드가 혼자서 일을 처리하지만, 들어오는 요청 순서가 아닌 논 블로킹 방식으로 이전 작업이 완료될 때까지 대기하지 않고 다음 작업을 수행한다.

💬 싱글 스레드 (Single Thread)

  • 장점: 리소스 관리에 효율적이다.
  • 단점: 스레드 기반 작업들의 효율이 떨어짐 (e.g. CPU 연산 작업)

Node.js는 비동기 동작으로 스레드 기반의 작업을 최소화한다.

💬 이벤트 기반 (Event-driven)

  • 이벤트 기반이란, 이벤트가 발생할 떄 미리 지정해둔 작업을 수행하는 방식을 의미한다.
  • 즉, 이벤트 기반 시스템에서는 특정 이벤트가 발생할 때 무엇을 할지 미리 등록해두고, 이를 이벤트 리스너에 콜백 함수를 등록한다.
  • 이후 이벤트가 발생하면 리스너에 등록해둔 콜백 함수를 호출하며, 이벤트가 끝난 후 노드는 다음 이벤트가 발생할 때까지 대기한다.

💬 이벤트 루프 (event loop)

  • 이벤트 루프는 여러 이벤트가 동시에 발생했을 때, 어떤 순서로 콜백 함수를 호출할지 판단한다.
  • 이벤트가 종료될 때까지 이벤트 처리를 위한 작업을 반복하므로 루프(loop)라고 부른다.
  1. 클라이언트가 웹 서버에 HTTP 요청을 하게 되면 서버에서는 이벤트 루프가 돌고 있다가 요청을 감지하고 알맞은 작업을 워커 스레드를 생성하여 실행한다.
  2. 이때 이벤트 루프는 해당 워커 스레드가 작업을 마친 뒤 그 결과와 함께 응답할 때까지 기다리는 것이 아닌 바로 루프로 복귀하여 다른 요청을 기다리게 된다.
  • 즉, 이벤트 루프는 어떤 요청이 발생하면 그 작업에 대해 스레드 실행만 일으킨다. 이후 작업을 할당받았던 해당 스레드가 모든 작업을 마치면 전달받은 콜백 함수를 실행하여 이벤트 루프로 응답하고, 이벤트 루프가 이를 실행하여 클라이언트에게 결과를 보내준다.

💬 논블로킹 I/O (Non-Blocking I/O)

Node.js 라이브러리의 모든 API는 비동기식(async)이고 멈추지 않는다(Non-blocking).
Node.js 기반 서버는 API가 실행되었을 때, 데이터를 반환할 때까지 기다리지 않고 다음 API를 실행한다.

  • 작업을 처리할 때 이벤트 루프가 나머지 요청을 막지 않고 계속 요청을 받는 방식이다

  • 요청을 차단하는 대신 모든 작업이 즉시 실행되며, 요청이 즉시 큐에 대기되고 함수가 반환됨을 의미한다. (실제 I/O는 나중에 처리된다.)

Node.js의 작동 원리

입출력은 이벤트 루프 기반의 싱글 스레드로, 실직적인 작업은 멀티 스레드로 실행한다.

이 원리를 푸드 코트를 예로 들어 비유를 해보자.

  1. 주문은 한곳에서 받고, 실직적인 요리는 각 식당에서 만든다.
  2. 음식이 완료되면 각 식당에서 호출 벨을 통해 손님을 부르고, 손님은 음식을 픽업한다.

여기서 계산을 담당하는 작업이 싱글 스레드이고, 각 요리를 완성해 벨을 호출하는 식당들이 thread pool을 통한 멀티 스레드 비동기 방식이다.

즉, 입력은 하나의 스레드에서 받지만, 순서대로 처리하는 방식이 아닌 먼저 처리된 결과 값을 이벤트로 반환해 주는 방식이 Node.js가 사용하는 싱글 스레드 비동기 방식이다.

여기서, thread pool을 관리하는 것은 개발자가 아니라 플랫폼이다. 개발자가 스레드 하나를 관리하듯이 프로그래밍하면 플랫폼이 여러 스레드를 효율적으로 운용하게 된다.

Node.js의 장/단점

장점

  • 자바스크립트로 Back-end 개발 환경을 구성할 수 있어 생산성이 높고 러닝 커브가 낮다.
  • 단일 스레드의 논 블로킹 이벤트 기반 비동식 방식으로 처리되어 높은 처리 성능을 가지며, 서버 부하가 적다.
  • 다양한 패키지 매니저(NPM: Node package Manager)를 기반으로 다양한 모듈(패키지)을 제공하여 자신이 필요한 라이브러리와 패키지를 사용할 수 있어 효율성이 좋다.

단점

  • 서버단 로직이 복잡한 경우 콜백 함수의 늪(Callback Hell)에 빠질 수 있다.
  • 단일 스레드이기 때문에 하나의 작업이 오래 걸리는 웹 서비스의 경우 애플리케이션의 성능이 저하될 수 있다.
  • 코드가 수행되어야 코드에 에러가 있는지 알 수 있으며, 에러가 날 경우 프로세스가 내려갈 수 있다.
  • 세션을 공유할 경우 Redis와 같은 부가적인 인프라가 필요하다.
    (Node 프로젝트에서 pm2로 다중 클러스터 인프라를 구축했다면 세션 불일치 문제가 생기게 마련이다.
    서버가 종료되어 메모리가 날라가면 접속자들의 로그인이 모두 풀려버리게 된다.)

Node.js가 어울리는 웹서비스

  • 간단한 로직인 경우
  • 대용량 처리가 필요한 경우(동시의 여러 요청을 처리)
  • 빠른 응답시간을 요구
  • 비동기 방식에 어울리는 웹 서비스(네트워크 스트리밍 서비스, 채팅 서비스 등)

Node.js가 어울리지 않는 웹서비스

  • 단일 처리가 오래 걸리는 경우 -> 싱글 스레드 기반이기 때문이다.
  • 서버 체크 로직이 많은 경우 -> 논 블로킹 I/O 기반이기 때문에 콜백 헬에 빠지기 쉽다.
  • 업무 복잡도/난이도가 높은 경우 -> 에러 발생 시 서버가 다운되기 때문에 코드 품질이 중요하다.

✨ 정리 ✨

  1. 하나의 언어로 Front/Back-end 개발 환경을 구성할 때 유용하다.
  2. 간단한 로직으로 구성하는 서비스에 사용하는 것이 좋다.
  3. 입출력(I/O)이 자주 발생하면 노드를 서버로 사용하는 것이 좋다.
  4. 빠르게 환경 구성을 하여 개발을 해야 하는 경우에 유용하다.

추가로,

  • 웹 서버가 내장되어 있어 별도의 웹서버를 설치할 필요가 없으며,
  • 자바스크립트를 사용하기 때문에 JSON 형식과 쉽게 호환된다.
  • 클러스터링을 통해 프로세스를 포크(fork) 하여 멀티 스레드인 것처럼 사용할 수 있다.

참고
https://junspapa-itdev.tistory.com/3
https://hanamon.kr/nodejs-%EA%B0%9C%EB%85%90-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0/
https://hanamon.kr/nodejs-%EA%B0%9C%EB%85%90-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0/
https://velog.io/@deannn/Node.js-Node.js%EC%9D%98-%EC%86%8C%EA%B0%9C%EC%99%80-%ED%8A%B9%EC%A7%95
https://inpa.tistory.com/entry/REDIS-NODE-%F0%9F%93%9A-%EB%85%B8%EB%93%9Cexpress%EC%97%90%EC%84%9C-redis-%EC%82%AC%EC%9A%A9%EB%B2%95-%EC%BA%90%EC%8B%B1-%EC%84%B8%EC%85%98-%EC%8A%A4%ED%86%A0%EC%96%B4

profile
👩🏻‍🌾기억을 기록하고 공유하자📚

0개의 댓글