개발은 재밌어야 한다
article thumbnail
Published 2021. 7. 20. 13:29
NodeJs 개념 정리 javascript/Nodejs
반응형

노드가 무엇인지에 대해 여러가지 의견이 많지만, 어떠한 설명도 노드 공식 사이트(https://nodejs.org/ko/)의 설명보다 정확하지는 않을 것입니다.
노드 공식 사이트에서는 노드를 다음과 같이 설명하고 있습니다.

노드는 자바스크립트 런타임입니다. 여기서 런타임이란 특정 언어로 만든 프로그램들을 실행할 수 있는 환경을 뜻합니다. 

따라서 노드는 자바스크립트 프로그램을 컴퓨터에서 실행할 수 있습니다.

쉽게 말해 노드는 자바스크립트 실행기라고 생각하면 됩니다.

 

기존에는 자바스크립트 프로그램을 웹 브라우저 위에서만 실행할 수 있었습니다. 브라우저는 기본적으로 자바스크립트 런타임을 내장하고 있으므로 자바스크립트 코드를 실행할 수 있습니다.

브라우저 외의 환경에서 자바스크립트를 실행하기 위한 여러 시도가 있었으나, 자바스크립트의 실행 속도 문제 때문에 모두 큰 호응을 얻지는 못했습니다.

2008년 구글이 V8 엔진을 사용하여 크롬을 출시하고 V8엔진은 다른 자바스크립트 엔진과 달리 매우 빨랐고, 오픈 소스로 코드를 공개했습니다. (https://github.com/v8/v8)속도 문제가 해결되고 라이언 달이 2009년 V8 엔진 기반의 노드 프로젝트를 만들게 되었습니다.

즉, NodeJs는 브라우저에서만 구동되던 JavaScript의 환경을 브라우저 바깥세상으로 나오게 하는 역할을 하게 된 것입니다.

노드의 내부 구조

노드는 V8과 더불어 libuv라는 라이브러리를 사용합니다.

V8과 libuv는 C와 C++로 구현되어 있습니다. 

자바스크립트 코드는 노드가 알아서 V8과 libuv에 연결해주므로 노드를 사용할때 C와 C++는 몰라도 상관이 없습니다.

 

libuv 라이브러리는 노드의 특성인 이벤트 기반, 논 블로킹 I/O모델을 구현하고 있습니다. 이 모델의 특징과 장단점을 알아보겠습니다.

 

이벤트 기반(event-driven) 이란 이벤트가 발생할 때 미리 지정해둔 작업을 수행하는 방식을 의미합니다.
이벤트로는 클릭이나 네트워크 요청 등이 있을 수 있습니다.
이벤트 기반 시스템에서는 특정 이벤트가 발생할 때 무엇을 할지 미리 등록해두어야 합니다.
이를 이벤트 리스너(event listener)에 콜백(callback)함수를 등록한다고 표현합니다. 
버튼을 클릭할 때 경고창을 띄우도록 설정하는 것을 예로 들어보겠습니다.
클릭 이벤트 리스너에 경고창을 띄우는 콜백함수를 등록해두면 클릭 이벤트가 발생할 때마다 콜백 함수가 실행되어 경고창이 뜨는 것입니다.


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

이벤트 기반 모델에서는 이벤트 루프(event loop)라는 개념이 등장합니다. 여러 이벤트가 동시에 발생했을 때 어떤 순서로 콜백 함수를 호출할지를 이벤트 루프가 판단합니다.

 

- 이벤트 루프란(event loop)란?

Callback Event Queue에서 하나씩 꺼내서 동작시키는 Loop를 말합니다.

이벤트나 메세지를 대기하다가 디스패치하는 프로그래밍 구조체인데, 자바스크립트는 싱글 스레드(Single-thread)이다.

하나의 스레드 밖에 없기 때문에 한번에 한 동작만 실행될 수 있다고 생각할 수 있으나, 그렇지 않다. 우리가 흔하게 볼 수 있는 웹페이지를 보면 동시에 마우스 클릭 이벤트를 처리하는 페이지들을 볼 수 있다. 이것이 바로 자바스크립트의 동시성(Concurrency)이다.

그렇다면 자바스크립트의 동시성은 누가 하는가? 바로 이 자바스크립트 엔진을 구동하는 환경, 즉 브라우저나 Node.js가 담당한다.

 

브라우저의 환경

실제로 우리가 비동기 호출을 위해 사용하는 setTimeout이나 XMLHttpRequest와 같은 함수들은 자바스크립트 엔진이 아닌 Web API 영역에 따로 정의되어 있다. 또한 이벤트 루프와 태스크 큐와 같은 장치도 자바스크립트 엔진 외부에 구현되어 있는 것을 볼 수 있다.

 

다음은 Node.js의 환경을 보자

이 그림에서도 브라우저의 환경과 비슷한 구조를 볼 수 있다. Node.js는 비동기 IO를 지원하기 위해 libuv라이브러리를 사용하여, 이 libuv가 이벤트 루프를 제공합니다. 자바스크립트 엔진은 비동기 작업을 위해 Node.js의 API를 호출하며, 이때 넘겨진 콜백은 libuv의 이벤트 루프를 통해 스케쥴되고 실행합니다.

 

 

 

 

 

 

 

 

 

반응형
profile

개발은 재밌어야 한다

@ghyeong

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!