본문 바로가기

Node JS

[혼자 공부] Node.js 개념 이해

1. 노드의 핵심 개념을 이해하자


  • 뭐든지 공부를 할 때, 핵심 개념을 충분히 이해하지 못하고 들어가면 의문점이 생기는 포인트가 많이 생기는 경우가 있다. 개념을 이해하고 코드를 작성할 때, 생산성을 높이며 코딩을 시작하자.

 

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

이것은 노드 공식 사이트에서 노드를 이와 같이 설명하고 있습니다. 대부분은 노드를 서버로 사용하는 방법을 익히지만 서버 외의 자바스크립트 프로그램을 실행하는 런타임으로 사용하는 방법을 배우는 것이 좋다.

런타임이란? 특정 언어로 만든 프로그램을 실행할 수 있는 환경을 의미합니다. 따라서, 노드는 자바스크립트 프로그램을 컴퓨터에서 실행할 수 있다는 것을 의미합니다.

기존에는 자바스크립트 프로그램을 웹 브라우저 위에서만 실행할 수 있었습니다. 하지만 구글이 V8 엔진을 사용하여 크롬을 출시함으로써, 속도 문제가 상당히 개선되었습니다.

노드는 V8과 더불어 libuv라는 라이브러리를 사용합니다. V8과 libuv는 C와 C++로 구현되어있지만, 우리가 코딩한 자바스크립트 코드는 노드가 알아서 연결함으로 C와 C++는 무관하다.

노드를 공부 할 때, 알아야 할 요소가 있는데 이것은 libuv의 특성과 연관이 있다.

 

이벤트 기반


1.이벤트가 발생할 때 미리 지정해둔 작업을 수행하는 방식을 의미한다. 자바나 코틀린을 통해 한번쯤 코딩해본 사람들은 익숙하게 들릴 수 있다. 예를 들어, 버튼에 대해 리스너에 작업을 등록하면 버튼을 누를 때마다 작업이 수행됩니다.

노드도 이벤트 기반 방식으로 동작하므로, 이벤트가 발생하면 이벤트 리스너에 등록해둔 콜백 함수를 호출합니다. 이에 대해서는 자세히 뒤에서 설명하겠습니다. ( 콜백 함수의 실행 순서 등등)

 

Event Loop(이벤트 루프)

여기서부터 코드 실행 순서, 함수 호출 및 실행, 콜백 함수 등 중요한 것이 나오니 명확하게 이해해야 한다.

여러 이벤트가 동시에 발생했을 때 어떤 순서로 콜백 함수를 호출할지를 이벤트 루프가 판단한다. 노드는 자바스크립트 코드의 맨 위에서부터 순서대로 한 줄씩 실행합니다. 여기까지는 단순하게 이해가 됩니다. 하지만 다음 코드는 어떤 순서로 실행되어 로그를 남길까?

 

function first(){
	second();
    consol.log('첫 번째');
}

function second(){
	third();
    consol.log('두 번째');
}

function third(){
    consol.log('세 번째');
}

first();

 

설명하기에 앞서 컨텍스트(Context)가 무엇인지 알고 넘어가야 한다. 콘텍스트는 함수가 호출되었을 때 생성되는 환경을 의미합니다. 자바스크립트 코드는 기본적으로 전역 콘텍스트 안에서 돌아간다고 생각하는 게 좋다. anonymous 함수가 처음 실행 시의 전역 콘텍스트를 의미합니다.

아래와 같이 호출 스택을 통해서 어떻게 실행되는지 알아보자.

함수를 호출 한다고 바로 실행되는 것이 아니라 호출 스택에 머물러 있다가 실행이 완료되면 호출 스택에서 지워진다.

 

호출 스택과 로그가 어떻게 찍히는지 알 수 있다.

 

정확히 짚고 넘어가야 할 DEFINITION


이벤트 루프(Event Loop)
- 이벤트 발생 시 호출할 콜백 함수들을 관리하고, 호출된 콜백 함수의 실행 순서를 결정하는 역할을 담당 노드가 종료될 때까지 반복하므로 루프라고 부른다.

백그라운드(BackGround)
-타이머나 이벤트 리스너들이 대기하는 곳, 여러 작업이 동시에 실행될 수 있다(ex: I/O 작업)

태스크 큐(Task Queue)
- 이벤트 발생 후, 백그라운드에서는 태스크 큐로 타이머나 이벤트 리스너의 콜백 함수를 보내는데, 정해진 순서대로 콜백들이 줄을 서 있으므로 콜백 큐라고도 부른다.

 

추가적으로, NonBlocking I/O의 개념은 운영체제를 공부한 사람은 쉽게 이해할 수 있으니 간단하게만 예시로 설명하고 생략하겠습니다.

 

Blocking I/O는 Block의 의미를 생각해보면 쉽습니다. 작업1, 작업 2, 작업 3가 순서대로 존재할 때, 작업 1이 완료될 때까지 대기, 완료 후 작업 2가 완료될 때까지 대기... 이런 식으로 대기하는 시간이 존재하게 되고 CPU를 이용하는 데 있어서 낭비라고 볼 수 있다. 하지만 NON Blocking은 이전 작업이 완료될 때까지 대기하는 것이 아니라 다음 작업들을 수행할 수 있다고 이해하면 쉬울 것이다.

 

SINGLE THREAD(싱글 스레드)?

스레드에 대한 개념도 운영체제에서 배운다. 하지만 짚고 넘어가야 할 것이 있다. 노드가 싱글 스레드라는 말을 들어봤을 텐데 엄밀히 말하면 노드는 싱글 스레드로 동작하지 않습니다. 노드를 실행하면 먼저 프로세스가 생성되고, 이 프로세스에서 스레드를 생성하는데, 이 때 내부적으로 스레드를 여러 개 생성합니다. 이 중에 직접 제어할 수 있는 스레드가 하나이기 때문에 흔히 노드가 싱글 스레드라고 여겨지는 것이다.

 

노드가 싱글 스레드로 동작하지 않는 2가지 경우

1. 스레드 풀

2. 워커 스레드

 

이것에 대해서는 나중에 자세히 다루겠습니다.

 

노드의 장단점


노드를 서버로 사용할 때, 특히 I/O 작업이 많은 경우 장점을 발휘합니다. but, CPU 부하가 큰 작업에는 적합하지 않다.
싱글 스레드로서, libuv 라이브러리를 사용하여 I/O 작업을 비동기 처리하기에 많은 수의 I/O를 혼자서 감당할 수 있지만 CPU 부하가 크면 감당하기 어렵습니다.

EX) 개수가 많더라도 작은 데이터를 주고 받을 때 -> Network, Database, Disk 작업 등등

언어는 무엇을 사용할까?
자바스크립트를 사용하기 때문에 큰 장점이다. 웹 브라우저도 자바스크립트를 사용하기에 서버까지 노드를 사용한다면 하나의 언어로 생산성이 크게 향상된다.

또한 데이터를 주고 받을 때, JSON을 사용할 수 있는데 JSON이 자바스크립트 형식이므로 노드에서 쉽게 처리를 할 수 있습니다.

 

(Node.js 교과서 개정 2판 조현영 지음 책을 바탕으로 제가 직접 이해하고 인용한 글들이 있습니다.)

'Node JS' 카테고리의 다른 글

[혼자 공부] Node.js 2장 알아두어야할 자바스크립트  (0) 2021.07.28