dh_0e

[Node.js] 강의 내용 개념 정리(2) (Node.js, 논 블로킹 I/O, 싱글 스레드, 이벤트 루프) 본문

내일배움캠프/Node.js[입문]

[Node.js] 강의 내용 개념 정리(2) (Node.js, 논 블로킹 I/O, 싱글 스레드, 이벤트 루프)

dh_0e 2024. 5. 14. 00:00

JavaScript: 정적인(Static) 문서를 조금 더 동적(Dynamic)으로 표현할 수 있도록 만들어짐

 

정적(Static) 페이지 vs 동적(Dynamic) 페이지

정적 웹 페이지 (Static Web Page)

- 미리 작성되어 확정된 페이지로 실시간 정보나 맥락을 반영하지 못하며 추가적인 연산이 없으므로 HTML로만 작성 가능

 

동적 웹 페이지 (Dynamic Web Page)

- 맥락, 상황을 반영할 수 있는 페이지

- NetScape를 시작으로 브라우저를 만드는 각 회사에서 다양한 언어를 개발하기 시작함

- ECMA International에 의해 이를 표준화 시켜 ECMAScript라는 이름으로 자바스크립트 표준을 제정함

- Java라는 언어의 인기에 편승하기 위해 지어진 이름으로 전혀 관계가 없음

 

Node.js

- Chrome V8 JavaScript 엔진으로 빌드된 JavaScript 런타임.

출처: https://www.korecmblog.com/node-js-event-loop/

- "JavaScript를 브라우저가 아닌 컴퓨터에서 브라우저 없이 실행하게 도와주는 환경"

- V8 엔진: 구글이 개발하여 구글 크롬 브라우저에서 사용하는 자바스크립트 엔진으로 Node.js에서 이 엔진을 활용함으로써, 브라우저 환경 이외에서도 자바스크립트를 사용할 수 있게 됨

- libuv: Node.js가 비동기 I/O 작업을 수행할 수 있게 해주는 중요한 라이브러리. 이 덕분에 논 블로킹 I/O 모델이라는 특징과 여러 요청을 효율적으로 처리할 수 있게 됨

- 이 두 가지 주요 구성 요소는 C/C++로 작성되어 있음 / Node.js가 연결 및 상호 작용을 자동으로 처리해줌

 

브라우저가 아닌 컴퓨터에서 브라우저 없이 실행하게 도와주는 환경??

by ChatGPT

 

 

Node.js의 장점

출처: https://survey.stackoverflow.co/2023/

- 2023 스택오버플로우 설문에서 웹 프레임워크 기술 부문에서 1위를 차지할 정도로 대표적인 웹 프레임워크 기술

- 논 블로킹(Non-blocking) I/O, 싱글 스레드(Single Thread), 이벤트 루프(Event Loop)의 특성을 가지고 있음

 

논 블로킹 I/O

- 블로킹 방식: 프로그램이 특정 작업을 수행하는 동안 다른 작업을 중단시키는 방식

- 논 블로킹 방식: 프로그램이 여러 작업을 동시에 처리하는 방식

- I/O는 데이터의 입력(Input) / 출력(Output)을 의미하며, 파일을 저장, 불러오는 것을 의미

블로킹 I/O: 한 번에 하나의 작업만을 처리, 호출된 함수가 자신의 작업을 모두 마칠 때까지 호출한 함수에게 제어권을 넘겨주지 않음 (동기적)

논 블로킹 I/O: 시스템 호출이 완료되기를 기다리지 않고 바로 다음 작업으로 즉시 넘어갈 수 있는 방식, 호출된 함수는 작업의 완료 여부와 상관없이 즉시 제어권을 호출한 함수에게 반환함 (비동기적)

 

싱글 스레드(Single Thread)

- 스레드 하나를 사용하는 것이며, 동시에 하나의 작업만을 처리할 수 있음을 의미

스레드(Thread): 프로그램이 동작할 때, CPU 또는 프로세서를 사용하는 단위, 여러 스레드를 사용하면 여러 작업을 동시에 처리할 수 있지만 복잡성을 증가시키고 리소스를 더욱 많이 소모하게 되는 문제점이 발생함

- Node.js는 싱글 스레드로 동작하지만 I/O작업이 발생한 경우 이를 비동기적으로 처리하여 여러 작업을 동시에 처리할 수 있게 함

 

Node.js가 싱글 스레드를 고집하는 이유?

- 스레드 생성, 관리에 드는 부담을 줄여줌, 컴퓨팅 리소스를 효율적으로 사용할 수 있게 함, 동시성 문제, 즉 여러 스레드가 공유하는 자원에 대한 동시접근 문제를 방지함

- 멀티스레드 방식으로 웹 서버에서 동시에 많은 요청 처리할시 요청마다 스레드를 생성해야 하므로 오버헤드가 크게 발생

- Node.js의 싱글 스레드 + 이벤트 루프 방식을 사용하면, 동시에 많은 요청을 효율적으로 처리 가능

- 이러한 특징으로 인해 연결 요청의 부하에 따른 서버 확장이 매우 자유로움. 웹 서버에 특화된 철학이 녹아있음

- but, 싱글 스레드 방식은 CPU 집중적인 작업에는 적합하지 않음!

 

호출 스택: 함수의 실행 순서를 추적하는 자료구조

- 비동기 작업에서 문제가 됨, 네트워크 요청과 같이 시간이 많이 걸리는 작업을 기다리는 동안 JavaScript는 다른 어떠한 작업도 처리할 수 없게 됨.

- 이러한 문제를 해결하기 위해 JavaScript는 이벤트 루프(Event Loop), 이벤트 큐(Event Queue)를 사용하게 됨.

 

이벤트 루프(Event Loop)

- 여러 이벤트들과 같은 비동기 작업들을 모아서 관리, 어떤 순서로 실행해야 하는지 도와주는 도구

- 호출 스택과 이벤트 큐를 관찰하면서, 호출 스택이 비어있고, 이벤트 큐에 작업이 있다면, 이벤트 큐의 작업을 호출 스택으로 이동하는 역할을 담당함

- 이를 활용하면 시간이 오래 걸리는 작업을 이벤트 큐에 넣어 비동기적으로 처리하고, 그 동안 호출 스택에서 다른 작업들을 계속 처리할 수 있음

 

이벤트 루프의 동작 방식 ex)

function firstFunction() {
  console.log('firstFunction 입니다.');
  secondFunction();
}

function secondFunction() {
  // 2 초간 기다린다.
  setTimeout(function () {
    console.log('secondFunction 입니다.');
  }, 2000);
}

firstFunction();
console.log('전역 코드 실행 중!');

// print: firstFunction 입니다.
// print: 전역 코드 실행 중!
/** 2 초간 기다린다. **/
// print: secondFunction 입니다.

 동작 순서

>> main에서 firstFunction 호출 (콜 스택)

>> firstFuinction에서 콘솔 출력 및 secondFunction 호출 (콜 스택)

>> setTimeout은 비동기 함수로 JavaScript는 이 작업을 이벤트 큐에 넣고 secondFunction을 호출 스택에서 제거함

>> secondFunction과 firstFunction을 콜 스택에서 제거하고 콘솔 출력

>> 2초 후 setTimeout이 이벤트 큐에서 콜 스택으로 이동하고 실행됨 (콜 스택이 비어있었기 때문)