Node.js 이해하기2(ft.이론편)

shooting star·2024년 5월 8일
0
post-thumbnail

들어가며

Node.js는 자바스크립트를 브라우저 밖에서도 실행할 수 있게 해주는 자바스크립트 런타임입니다. 그 핵심은 V8 엔진과 libuv 라이브러리, 그리고 이벤트 루프에 있습니다. 이번 글에서는 Node.js가 어떻게 작업을 처리하고 비동기 I/O를 효율적으로 수행하는지 살펴보겠습니다.

Node.js 런타임 환경 이해하기

V8 엔진과 Libuv

출처 : https://www.appinessworld.com/blogs/267/serverside-development-with-nodejs

Node.js 런타임 환경은 크게 두 부분으로 구성됩니다:

  • V8 엔진: JavaScript 코드를 실행하고 해석합니다. 간단한 수학 연산(1 + 1) 같은 작업을 처리합니다.
  • Libuv: V8이 처리하지 못하는 파일 읽기, 네트워크 요청 같은 작업을 담당하는 다중 플랫폼 비동기 I/O 라이브러리입니다.

Node.js 런타임 환경 구조

  1. V8 엔진: 자바스크립트 코드를 실행
  2. Libuv: 비동기 I/O 작업 처리 (파일 시스템, 네트워크, DNS 등)
  3. Node.js API: HTTP 모듈, 파일 시스템 모듈, Crypto 모듈 등
  4. Node.js 바인딩: 자바스크립트 코드와 C/C++ 코드를 연결하여 libuv 라이브러리와 상호작용

작업 처리 흐름 이해하기

Node.js가 비동기 I/O 작업을 어떻게 처리하는지 알아봅시다. 예를 들어, 인터넷에서 파일을 다운로드해야 한다면 다음과 같은 순서로 작업이 진행됩니다.

  1. 요청: http 모듈 API를 통해 자바스크립트 코드로 다운로드 요청을 보냅니다.
  2. libuv로 작업 전달: Node.js 바인딩을 통해 libuv에 작업을 전달합니다.
  3. 비동기 작업 처리: libuv는 네트워크 I/O 작업을 처리합니다.
  4. 이벤트 루프 대기: 이 시간 동안 자바스크립트는 다른 작업을 할 수 있습니다.
  5. 콜백 실행: 작업이 완료되면 libuv는 이벤트 루프를 통해 콜백을 실행합니다.

이러한 구조 덕분에 Node.js는 단일 스레드에서도 다수의 I/O 작업을 동시에 처리할 수 있습니다.

libuv는 이벤트 루프를 기반으로 하는 비동기 I/O 지원을 제공하는 다중 플랫폼 C 라이브러리입니다. Node.js뿐만 아니라 Julia, Luvit, pyuv 등의 다른 도구에서도 사용됩니다. 주요 기능으로는 파일 시스템, DNS, 네트워크, 파이프, 신호 처리, 폴링 및 스트리밍 등이 있습니다.

이벤트 루프 이해하기

Node.js의 이벤트 루프는 작업을 처리하고 비동기 작업을 효율적으로 관리하기 위한 핵심 구현체입니다.

동기 vs 비동기

  • 동기 작업 (Synchronous): 한 번에 하나의 작업만 처리 (예: for 루프)
  • 비동기 작업 (Asynchronous): 여러 작업을 동시에 처리 (예: setTimeout, fs.readFile)

Node.js는 싱글 스레드이지만 이벤트 루프와 libuv를 통해 비동기 I/O 작업을 효율적으로 처리합니다.

이벤트 루프의 단계

  1. Timers: setTimeoutsetInterval 콜백 실행
  2. Pending Callbacks: 시스템 작업 콜백 실행
  3. Idle, Prepare: 내부적으로 사용
  4. Poll: 대부분의 I/O 관련 콜백 실행
  5. Check: setImmediate 콜백 실행
  6. Close Callbacks: 소켓 및 프로세스 종료 콜백 실행

예시: setImmediatesetTimeout

  • setImmediate: 이벤트 루프의 Check 단계에서 처리
  • setTimeout: 이벤트 루프의 Timers 단계에서 처리

예를 들어, 파일을 읽는 작업을 통해 setImmediatesetTimeout이 어떻게 다르게 실행되는지 알아보겠습니다.

const fs = require('fs');

fs.readFile('example.txt', () => {
    console.log('File read complete');

    setImmediate(() => {
        console.log('SetImmediate callback');
    });

    setTimeout(() => {
        console.log('SetTimeout callback');
    }, 0);
});

결과 분석

  1. 파일 읽기 작업 완료
  2. SetImmediate 콜백 실행
  3. SetTimeout 콜백 실행

이유: 이벤트 루프에서 파일 읽기 작업은 Poll 단계에서 완료됩니다. 이후 Check 단계에서 setImmediate 콜백이 먼저 실행되고, Timers 단계에서 setTimeout 콜백이 실행됩니다.

요약

Node.js는 V8 엔진, libuv 라이브러리, 그리고 이벤트 루프를 통해 비동기 I/O 작업을 효율적으로 처리합니다. 이를 통해 Node.js는 싱글 스레드에서도 다수의 I/O 작업을 동시에 처리할 수 있습니다.

핵심 요약

  1. V8 엔진: 자바스크립트 코드를 실행하고 해석
  2. Libuv: V8이 처리하지 못하는 비동기 I/O 작업 처리
  3. 이벤트 루프: 여러 비동기 작업을 관리하고 순서대로 실행

Node.js의 오픈 소스 코드를 통해 이러한 원리와 흐름을 더 깊이 이해하고 응용할 수 있습니다.

참고 자료

0개의 댓글