[TIL / Node.js] Node.js 의 비동기 원리

알락·2022년 10월 10일
0

Node.js 도 비동기로 작동하나?

node.js logo

웹 브라우저에서 자바스크립트가 어떻게 작동하는 지를 살펴보고 난 이후에 생긴 궁금증이다.
백엔드 쪽에서 사용하기 위해 만들어진 Node.js에서는 코드가 어떻게 작동을 할지에 대해서 말이다. Node.js "About" 페이지에는 간단하게 설명한다.

As an asynchronous event-driven JavaScript runtime, Node.js is designed to build scalable network applications. In the following "hello world" example, many connections can be handled concurrently. Upon each connection, the callback is fired, but if there is no work to be done, Node.js will sleep.
-> Node.js 웹페이지

"asynchronoius"는 비동기다. Node.js에서도 마찬가지로 비동기 프로그래밍을 지원한다. 이제 Node.js에서 어떻게 비동기 프로그래밍을 구현하는지 간단하게 살펴보려고 한다.


Libuv

Libuv 라이브러리는 C++로 작성되어 비동기 I/O 처리를 도와준다. 커널을 추상화해서 만들어 놓고, 커널이 처리할 수 있는 명령은 거기서 처리하고, 그렇지 않은 명령들은 쓰레드풀에 집어 넣어 다른 I/O 처리들을 동기적으로 처리한다.

아직 헷갈리는 것은 명령들을 집어 넣는 쓰레드풀과 이후 설명하는 이벤트루프가 같은 존재인지다.

그래서 Libuv는 Node.js의 I/O 작업을 위임받아 논 블로킹 I/O를 지원하고, 이 기반에는 I/O Loop가 있다고 한다.

I/O Loop

I/O Loop사진 출처: libuv 공식문서 i/o loop

Node.js에서 작성한 코드를 실행하면 우선 순서대로 명령을 수행하게 된다. 그 중 시간이 걸리는 I/O 처리가 있다면 LibuvI/O Loop를 생성해서 해당 명령이 속하는 큐에 집어넣어 잠시 실행을 보류하고 남아 있는 코드의 명령을 수행한다.
I/O Loop 총 6개의 Queue 로 구성되어 있다. 간단히 각각의 큐를 설명하겠다.

  • Timer : SetTimeout SetImmediate 함수를 관리하는 큐. Min-Heap으로 구현하여 시간이 짧은 순서대로 실행을 시키며, 효율적인 관리를 한다.
  • Pending Callback : 이전에 콜백 함수의 실행이 완료되었지만 그 결과를 반환하지 못한 것들을 처리해준다.
  • Idle, Prepare : 자바스크립트 실행에 영향을 미치지 않는 단계라고 한다.
  • Poll : Timer나 Check, Close 단계에 실행되는 함수들 이외 다른 모든 함수의 처리를 관리한다. 다른 큐와는 다르게 File DescriptorQueue를 사용하여 다른 Queue의 작업들을 확인하여 단계를 넘겨 나머지 지금 할 수 있는 작업들을 처리하고 돌아오는 등의 다른 효율적인 메커니즘을 수행한다.
  • Check : SetInterval 함수 실행을 관리한다.
  • Close : 소켓을 닫는 등의 함수 실행을 관리한다.

I/O Loop는 위의 6단계를 처음 Timer로 시작하여 모든 Queue의 실행되는 명령들을 수행할 때까지 순환한다. 앞의 코드의 즉각 실행 가능한 명령들은 비동기적으로 실행이 끝났고, 여기서부터는 개발자가 짜놓은 코드대로 Non-Blocking 하게 각 I/O 명령들을 처리하게 된다.\

참고

블로그 포스트 : Node.js 이벤트 루프(Event Loop) 샅샅이 분석하기

profile
블록체인 개발 공부 중입니다, 프로그래밍 공부합시다!

0개의 댓글