Node.js 시작

jxxm·2021년 7월 17일
0

Node.js

목록 보기
1/4
post-thumbnail

개념

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

런타임: 특정 언어로 만든 프로그램들을 실행할 수 있는 환경

JavaScript는 웹애플리케이션을 개발할 때 사용하는데, 이때 모든 브라우저는 JavaScript 코드를 해석하기 위해 JavaScript Engine을 내장하고 있다. (Chrome은 V8)

Node.js는 서버에서 JavaScript를 동작할 수 있도록, 서버로서 기능하기 위한 도구를 제공한다.

서버: 네트워크를 통해 클라이언트에 정보나 서비스를 제공하는 컴퓨터 또는 프로그램으로 클라이언트의 요청에 응답한다.

클라이언트: 요청을 보내는 주체로, 브라우저나 테스크톱 프로그램 그리고 다른 서버에 요청을 보내는 서버일 수도 있다.

웹 사이트를 방문하기 위해 주소창에 사이트 주소를 입력(요청) 
-> 브라우저는 주소에 해당하는 위치를 파악
-> 컴퓨터로부터 웹 사이트의 페이지를 받아와 요청자의 브라우저(클라이언트)띄운다(응답).

Node.js


이벤트 기반

이벤트가 발생할 때 미리 지정해둔 작업을 수행하는 방식

이벤트 기반 시스템에서는 특정 이벤트가 발생할 때 무엇을 할지 미리 등록해두어야 하는데, 이를 이벤트 리스터(event listener)콜백(callback) 함수를 등록한다고 표현한다.

노드는 이벤트 기반 방식으로 동작하기 때문에 이벤트가 발생하면 이벤트 리스너에 저장해둔 콜백 함수를 호출한다. 발생한 이벤트가 없거나 발생했던 이벤트를 다 처리하면, 다음 이벤트가 발생할 때 까지 대기한다.

여러 이벤트가 동시에 발생했을 때 어떤 순서로 콜백 함수를 호출할지를 이벤트 루프가 판단한다.

이벤트 루프(event loop): 이벤트 발생 시 호출할 콜백 함수들을 관리하고, 호출된 콜백 함수의 실행 순서를 결정하는 역할을 담당. 노드가 종료될 때까지 이벤트 처리를 위한 작업을 반복
백그라운드: setTimeout 같은 타이머나 이벤트 리스너들이 대기하는 곳
태스크 큐: 이벤트 발생 후, 백그라운드에서는 태스크 큐로 타이머나 이벤트 리스너의 콜백 함수를 보낸다.

function run(){
  console.log('3초 후 실행'); 
}

console.log('시작');
setTimeout(run, 3000);
console.log('끝');
[결과]
시작
끝
3초 후 실행

  1. 호출 스택에 먼저 전역 컨텍스트인 anonymous가 호출 스택에 들어가고, setTimeout이 호출 스택에 들어간다.
  2. setTimeout 실행 시, 콜백 run은 백그라운드로 보내고 setTimeout은 호출 스택에서 빠진다. 그리고 anonymous가 호출 스택에서 빠진다.
  3. 백그라운드에서는 3초를 센(백그라운드에 맡겨진 작업 완료) 후 run 함수를 태스크 큐로 보낸다.
  4. 호출 스택 실행이 끝나 비워지면 이벤트 루프가 태스크 큐의 run 콜백을 호출 스택에 넣고 실행한다.
  5. run이 호출 스택에서 실행되고 비워진다.
  6. 이벤트 루프는 태스크 큐에 콜백 함수가 들어올 때까지 계속 대기한다.

논 블로킹 I/O

이벤트 루프를 잘 활용하면 오래 걸리는 작업(동시에 실행될 수 있는 작업/동시에 실행될 수 없는 작업)을 효율적으로 처리할 수 있다.

자바스크립트 코드는 동시에 실행될 수 없는데, 자바스크립트 상에서 돌아가는 것이 아닌 Input/0utput 작업에서는 동시에 처리될 수 있다. 이러한 작업을 할 때 노드는 논블로킹 방식으로 처리한다.

블로킹: 이전 작업이 끝나야만 다음 작업을 수행

function longRunningTask(){
  // 오래 걸리는 작업
  console.log('작업 끝'); 
}

console.log('시작');
longRunningTask();
console.log('다음 작업');
[결과]
시작
작업 끝
다음 작업

논블로킹: 이전 작업이 완료될 때까지 대기하지 않고 다음 작업을 수행

function longRunningTask(){
  // 오래 걸리는 작업
  console.log('작업 끝'); 
}

console.log('시작');
setTimieout(longRunningTask(), 0);
console.log('다음 작업');
[결과]
시작
다음 작업
작업 끝

setTimieout(콜백, 0)은 코드를 논 블로킹으로 만들기 위해 사용하느 기법 중 하나이다.

이벤트 루프로 setTimeout의 콜백 함수인 longRunningTask가 태스크 큐로 보내지므로 순서대로 실행되지 않는다. 다음 작업이 먼저 실행된 후, 오래 걸리는 작업이 완료된다.


싱글스레드

프로세스: 운영체제에서 할당하는 작업의 단위로, 노드나 웹 브라우저 같은 프로그램은 개별 프로세스이다. 프로세스 간에는 메모리 등의 자원을 공유하지 않는다.
스레드: 프로세스 내에서 실행되는 흐름의 단위로, 프로세스는 스레드를 여러 개 생성해 여러 작업을 동시에 처리할 수 있다. 스레드들은 부모 프로세스 자원을 공유하고, 같은 주소 메모리 접근이 가능해 데이터를 공유할 수 있다.

노드는 싱글스레드이다.

정확히 말하면 노드는 싱글 스레드로 동작하지 않는다. 노드를 실행하면 먼저 프로세스가 하나 생성되고, 그 프로세스에서 스레드를 생성하는데 내부적으로 스레드를 여러 개 생성한다. 그중에서 직접 제어할 수 있는 스레드는 하나뿐이기 때문에 흔히 노드가 싱글 스레드라고 여겨진다.

요청이 많이 들어오면 한 번에 하나씩 요청을 처리한다. 블로킹이 심하게 일어나는 작업을 처리하지만 않으면 스레드는 하나로 충분하다. 블로킹이 발생할 것 같은 경우에 논 블로킹 방법으로 대기 시간을 줄인다.

싱글 스레드, 블로킹

싱글 스레드, 논 블로킹

멀티 스레드, 블로킹

멀티 스레딩멀티 프로세싱
하나의 프로세스 안에서 여러 개의 스레드 사용여러 개의 프로세스 사용
CPU 작업이 많을 때 사용I/O 요청이 많을 때 사용
프로그래밍이 어려움프로그래밍이 비교적 쉬움

I/O 작업을 처리할 때는 멀티 스레딩 보다 멀티 프로세싱이 효율적이므로 노드는 멀티 프로세싱을 많이 한다.


서버로서의 노드

노드는 기본적으로 싱글 스레드, 논 블로킹 모델을 사용하므로 싱글 스레드와 논 블로킹 모델의 장단점과 크게 다르지 않다.

서버에는 기본적으로 I/O 요청이 많이 발생하므로, I/O 처리를 잘하는 노드를 서버로 사용하면 좋다. 노드는 libuv 라이브러리를 사용하여 I/O 작업을 논 블로킹 방식으로 처리한다. 따라서 스레드 하나가 많은 수의 I/O를 혼자서도 감당할 수 있다. 하지만 CPU 부하가 큰 작업에는 적합하지 않다. 작성한 코드는 모두 스레드 하나에서 처리된다.

노드는 이와 같은 특성으로 개수는 많지만 크기는 작은 데이터를 실시간으로 주고받는 데 적합하다. 실시간 채딩 애플리케이션이나 주식 차트 JSON 데이터를 제공하는 API 서버가 노드를 많이 사용한다.

장점단점
멀티 스레드 방식에 비해 적은 컴퓨터 자원 사용기본적으로 싱글 스레드라서 CPU 코어를 하나만 사용
I/O 작업이 많은 서버로 적합CPU 작업이 많은 서버로는 부적합
멀티 스레드 방식보다 쉬움하나뿐인 스레드가 멈추지 않도록 관리가 필요함
웹 서버가 내장되어 있음서버 규모가 커졌을 때 서버를 관리하기 어려움
자바스크립트를 사용함어중간한 성능
JSON 형식과 쉽게 호환됨

0개의 댓글