TIL | <Node.js> Node.js의 장점

bubblegum·2024년 1월 17일
0

Today I learn(TIL)

목록 보기
13/84
post-thumbnail

1. 싱글 스레드

  • 스레드(Thread)란 프로그램이 동작할 때, CPU 또는 프로세서를 사용하는 단위로, 일반적으로 1개의 프로그램1개의 스레드를 사용할 수 있다. 1개의 프로그램에서 여러개의 스레드를 사용할 수 있다면 많은 작업을 동시에 처리할 수 있으므로 연산할 수 있는 시간을 단축 시킬 수 있다. 그러나 이는 복잡성을 증가시키고, 리소스를 더욱 많이 소모하게 되는 문제점이 발생한다.
  • 싱글 스레드(Single Thread)는 스레드 하나를 사용하는 것이며, 동시에 하나의 작업만을 처리할 수 있음을 의미한다. Node.js는 싱글 스레드로 동작하지만, I/O 작업이 발생한 경우 이를 비동기적으로 처리하여 여러 작업을 동시에 처리할 수 있게 한다.

  • 사실 싱글 스레드 방식은 많은 이점을 제공합니다. 스레드 생성과 관리에 드는 부담을 줄여주며, 컴퓨팅 리소스를 효율적으로 사용할 수 있게 합니다. 또한, 한 번에 하나의 작업만 처리하기 때문에 동시성 문제, 즉 여러 스레드가 공유하는 자원에 대한 동시접근 문제, 즉 Race condition 문제를 방지합니다.
    예를 들어, 웹 서버에서 동시에 많은 요청을 처리해야 하는 경우, 멀티스레드 방식을 사용하면 각 요청마다 스레드를 생성해야 하므로 오버헤드가 크게 발생합니다. 반면에 Node.js의 싱글 스레드 + 이벤트 루프 방식을 사용하면, 동시에 많은 요청을 효율적으로 처리할 수 있습니다.
    이러한 특징 덕분에 연결 요청의 부하에 따른 서버 확장이 매우 자유롭습니다. 즉, Node.js는 특히 웹 서버에 특화된 철학이 녹아있는 언어입니다.

  • 아무리 싱글 스레드만의 장점이 있다고 하더라도, 싱글 스레드 방식은 CPU 집중적인(CPU Intensive) 작업에는 적합하지 않습니다. 이런 경우에는 멀티스레드 방식이 더욱 효율적일 수 있습니다. 물론 이러한 약점을 극복하기 위해 Node.js 는 추가 스레드를 생성하는 방법들을 제공합니다만! 기본적으로 Node.js의 철학은 싱글 스레드 방식에 기반하고 있음을 기억해야 합니다.

2. 이벤트 루프와 이벤트 큐

  • 호출 스택(Call Stack)은 함수의 실행 순서를 추적하는 자료구조입니다. JavaScript는 코드를 실행하면서 호출 스택(Call Stack)함수를 추가(push)하고 함수가 완료되면 호출 스택에서 제거(pop)합니다. 이는 비동기 작업에서 문제가 되는데, 특히 네트워크 요청과 같이 시간이 많이 걸리는 작업을 기다리는동안 JavaScript는 다른 어떠한 작업도 처리할 수 없게 됩니다. 이 문제를 해결하기 위해 JavaScript는 이벤트 루프(Event Loop)와 이벤트 큐 (Event Queue)를 사용하게 됩니다.

  • 이벤트 루프(Event Loop)는 여러 이벤트들과 같은 비동기 작업들을 모아서 관리하고, 어떤 순서대로 실행해야하는지 도와주는 도구입니다. 이벤트 루프(Event Loop)는 호출 스택(Call Stack)과 이벤트 큐(Event Queue)를 관찰하면서, 호출 스택이 비어있고, 이벤트 큐에 작업이 있다면, 이벤트 큐의 작업을 호출 스택으로 이동하는 역할을 담당합니다. 이벤트 루프를 활용한다면, 자바스크립트는 시간이 오래 걸리는 작업을 이벤트 큐에 넣어 비동기적으로 처리하고, 그 동안 호출 스택에서 다른 작업들을 계속 처리할 수 있습니다.

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

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

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

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

위 예제 코드에서 firstFunction은 호출 스택에 추가(push)되고, 실행되며 ‘firstFunction 입니다.’를 콘솔에 출력하고 secondFunction을 호출 합니다. 그 다음 secondFunction은 호출 스택에 추가되고, setTimeout 함수를 실행합니다.

setTimeout은 비동기 함수이므로, JavaScript는 이 작업을 이벤트 큐에 넣고 secondFunction을 호출 스택에서 제거(pop)합니다. 그 다음 firstFunction도 호출 스택에서 제거하고, ‘전역 코드 실행 중!’을 콘솔에 출력합니다.

2초가 지난 후,secondFunction 입니다.’를 출력하는 작업이 이벤트 큐에서 호출 스택으로 이동하고 실행됩니다. 이때 호출 스택은 비어 있기 때문에 이벤트 루프가 이 작업을 호출 스택으로 이동시킬 수 있었습니다. 이처럼, 이벤트 루프와 이벤트 큐를 사용함으로써 JavaScript는 비동기 작업을 처리할 수 있게된 것입니다.

profile
황세민

0개의 댓글

관련 채용 정보