기억의 실마리
2022. 11. 27. 10:21

1. Node.js

자바스크립트를 개조해서 만들어진 런타임이다.

자바스크립트는 특정프로그램, 그중에서도

웹브라우저 안에서만 동작한다.

그런데, Node.js를 사용하면 터미널프로그램에서

node를 입력하여 브라우저없이 바로 실행이 가능하게 된다.

웹브라우저에서만 동작하는 자바스크립트의 한계를 극복하게 되고

이로써 서버를 만들 수 있게 되고 자바스크립트 단 하나의 언어로도

웹페이지를 만들 수 있게 해주는 런타임이다.

 

2. Node.js의 Single Thread

싱글스레드로 구성된 이벤트루프를 활용하여 요청을
받아들이고 스레드풀을 활용하여 병렬처리를 지원한다.

  • Node.js는 Non-Blocking 방식을 사용한다. 클라이언트로부터
    요청을 받으면 다른 스레드에게 요청을 전달한다. 그렇게 되면
    싱글스레드는 자유로워지고 바로 다음 요청을 받을 수 있게 된다.
    그렇게 두번째 요청을 받으면 또 다시 다른 스레드에게 전달하고
    두번째 요청을 전달받은 스레드는 다른서버나 DB에 쿼리를 날려
    요청을 처리한다.
  • asynchronous(비동기/async)방식을 사용하기 때문에
    클라이언트 요청을 처리한 스레드가 응답을 가져오면
    (스레드가 전달받은 요청을 서버 또는 DB에 쿼리를 날려 응답을 받아오면)
    콜백함수를 실행하게 된다.

 

3. 비동기 작업이 가능하게 된 이유

Node.js의 구조를 보면

v8 자바스크립트 엔진과 비동기 작업을 처리하는

libuv라는 라이브러리로 이루어져 있다.

v8에는 memory heap과 하나의 call stack이 있다.

(call stack은 싱글스레드와 같은 의미로 이해하자.)

memory heap은 메모리 할당이 일어나는 곳이며,

call stack은 코드 실행에 따라 호출스택이 차례대로 실행된다.

그렇기 때문에 v8에서는 비동기식 처리를 할 수가 없다.

 

즉, 비동기 작업을 가능하게 만들어 주는 것은 libuv라는 라이브러리가

Non-Blocking IO라는 기능을 가능하게 만들어주는 이벤트루프를

제공하기 때문이다. libuv는 c언어로 만들어졌고 시스템 커넬을 사용한다.

커넬은 멀티스레드를 사용하기 때문에 Node.js가 비동기처리를 할 수 있게 만든다.

 

4. eventLoop

  1. Node.js API로 요청이 들어오면, 들어온 요청은
    event queue(이하 큐)에 추가 된다.

  2. Node.js의 이벤트 루프는 큐를 리슨하여 들어온 요청이 있다면
    선착순으로 요청이 처리된다.

  3. 요청은 스레드풀로 보내진다. 스레드풀은 이벤트루프의 일부로서
    여러 요청을 수행할 수 있다. 이 후에는
    (이벤트루프는 큐에 요청이 있는지 리슨)  =>  (요청이있다면? 스레드풀로)
    이렇게 반복한다.

  4. 스레드풀은 DB또는 파일, 다른 서버 등에 보낸 요청을 수행한다.

  5. 요청 수행을 마쳤다면, 콜백함수를 실행시켜 이벤트 루프로 응답을 전달한다.
  6. 이벤트루프는 응답을 클라이언트로 보낸다.

 

5. 정리

Node.js는 자바스크립트 이벤트 기반 모델에서 영감을 받은

이벤트 루프가 있는 싱글 스레드이다. 자바스크립트와 비슷한 싱글 스레드 이지만

네트워크 호출, 파일시스템 작업 등과 같이 비동기적으로 수행되는 작업은

자바스크립트 코드가 아니라 thread pool에서 실행된다.

Node.js는 thread pool을 가지고 있고 멀티 스레드의 개념도 가지고 있다.

하지만 정의를 내리자면 자바스크립트 환경에서는

싱글 스레드로 사용된다 정의할 수 있다.