ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Node.js[2] - Event Loop, 주의사항
    Node.js 2018. 4. 1. 00:41





    - Event Loop



    Javascript의 큰 특징 중 하나는 'Single Thread' 기반의 언어라는 점이다.

    Thread가 하나라는 말은 곧, 동시에 하나의 작업만을 곧, 동시에 하나의 작업만 처리할 수 있다는 말이다.

    하지만 실제로 Javascript가 사용되는 환경을 생각하보면 많은 작업이 동시에 처리되고 있는걸 볼수 있다.

    예를 들면, 웹 브라우저는 애니메이션 효과를 보여주면서 마우스 입력을 받아서 처리하고, Node.js기반의 웹서버에서는 동시에 여러 개의 HTTP 요청을 처리하기도 한다. 

    여기서 드는 질문은 "어떻게 Thread가 하나인데 이런 일이 가능할까? " 다시 말해서 " Javascript는 어떻게 동시성(Concurrency)을 지원할까?"


    이때 등장하는 개념이 바로 'Event Loop'이다. 


    -    Google Chrome V8 엔진으로 개발되어 있으며, 프로그래밍 언어로는 Java script를 사용하며, Event 기반의 프로그래밍 모델


    V8과 같은 Javascript엔진에서는 단일 호출 스택을 사용하여 요청이 들어올때마다 해당 요청을 순차적으로 호출 스택에 쌓아놓는다. 이는 하나의 함수가 실행되면 이 함수의 실행이 끝날때 까지 다른 어떤 작업도 중간에 끼어들지 못한다.

    다시 말해 현재 스택에 쌓여있는 함수가 있다면 그 함수가 실행을 마치고 제거하기 전까지 다른 어떤 함수도 실행될수가 없다.

    (Run to Completion)

    그렇다면 비동기 요청과 동시성에 대한 처리는 어디서 할까?

    그것은 바로 자바스크립트 엔진을 구동하는 환경, 브라우저와 Node.js 에서 담당한다.


        

    위 두 개의 그림은 각각 브라우저와  Node.js 환경이다.

    왼쪽의 브라우저 환경에서 보여지듯이 JavaScript 엔진 밖에 Web APIs에서  비동기 처리에 대한 작업을 시행하며 Event Loop 와 Task Queue 도 외부에 존재한다.

    오른쪽의 Node.js 환경에서도 

    Node.js가 비동기 IO를 지원하기 위해 libuv 라이브러리를 사용하며 이 안에서 Event Queue 와 Event Loop 가 존재하며 V8 과의 별개의 영역을 가진다.


    다시 정리하자면 JavaScript가 'Single thread 기반의 언어' 라는 것은 '자바스크립트 엔진이 단일 호출 스택을 사용한다' 는 관점에서만 사실이며  실제 Javascript가 구동되는 환경(브라우저,Node.js등)에서는 주로 여러개의 thread가 사용되며, 이러한 구동 환경이 단일 호출 스택을 사용하는 Javascirpt 엔진과 상호 연동하기 위해 사용되는 장치가 바로 'Event Loop'인 것이다.


    좀더 Event Loop에 대해서 알아보기 위해 아래와 같은 예제 코드를 작성해보았다.



    function delay(){
    for(var i = 0; i < 100000; i++);
    }
    function lee(){
    delay();
    console.log('lee');
    }
    function min(){
    delay();
    lee();
    console.log('min');
    }
    function woo(){
    console.log('woo');
    }

    setTimeout(woo, 10);
    min();


    아래의 코드를 실행하면 ' lee min woo' 가 순서대로 실행되는 것을 확인할 수 있다.

    자바스크립트는 이벤트 기반의 언어 이기 때문에 setTimeout(woo, 10)에서 타이머 이벤트를 요청한후 스택에서 제거된다.

    그후 min 함수가 호출되어 스택에 쌓이게 되어 그후 lee 함수를 호출되고 lee 함수가 스택에 추가가 된다.

    그후 lee 함수가 실행을 마치면 스택에서 제거가 되고 마찬가지로 min 함수도 실행을 마치면 스택에서 제거가 된다.

    이렇게 호출 스택이 전부 비워지게 된후에 woo 함수가 스택에 추가되어 실행이 되어진다.


    그렇다면 woo 함수는 어떻게 min 함수가 끝나자마자 실행이 될수 있을까에 대한 궁금증이 생긴다.

    이에 대한 해답은 (테스크 큐 또는 이벤트 큐) 와 이벤트 루프에 있다.

    테스크 큐 또는 이벤트 큐는  콜백 함수들이 대기하는 큐(FIFO) 형태의 배열이고 이벤트 루프는 호출 스택이 비워질때마다 큐에서 콜백 함수를 꺼내와서 실행하는 역할을 한다.

    즉 이벤트 큐는 현재 실행중인 테스크가 없는지 와 테스크 큐 또는 이벤트 큐에 테스크가 있는지 를 반복적으로 확인한다.




    - Node.js 사용시 주의 사항



    Node.js는 이럴때 사용해라.

    가볍고 생산성이 높은 웹 개발 프레임워크을 가지고 있고 , 간단한 로직을 가지면서 대용량 그리고 빠른 응답 시간을 요구로 하는 애플리케이션을 개발할때


    Node.js는 이럴때 사용하지말아라.

    CPU 작업이 많은 애플리케이션에는 사용하지말아라. single thread 기반이라는 점을 다시 한번 상기해보면 하나의 request를 처리할때 CPU를 많이 사용하면 다른 요청 처리가 지연되게 되고, 전체적인 응답시간 저하를 연결한다.

    또한 main thread(single thread)를 멈추게 하는 CPU-Intensive Javascript 코드를 수행해야 하는 usecase는 node에서 사용하기엔 무리가 있다.

    CPU Intensive 라고하는 것들은 예를 들어 데이터분석,딥러닝,머신러닝할때 사용되는 수학연산을 들수 있겠다.



    Ref

    빠르게 훝어보는 node.js #1 - node.js 소개 및 내부구조

    자바스크립트와 이벤트 루프






    'Node.js' 카테고리의 다른 글

    Node.js - Webpack  (0) 2018.08.09
    Node.js - Babel  (0) 2018.08.07
    Node.js[JWT] - 토큰 기반 인증 - 2  (0) 2018.03.24
    Node.js[JWT] - 토큰 기반 인증 - 1  (0) 2018.02.24
    Node.js[1] - Single thread,Async,Callback  (0) 2018.02.16
Designed by Tistory.