ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백앤드에게 Event Loop란 무엇인가.(브라우저, Nest js, SpringBoot)
    Node.js/nest.js 2023. 3. 8. 23:51

    Javascript를 이해하려면 Event Loop가 무엇인지 알아야 한다. 
    구글에는 프론트 개발자 글이 많아서 브라우저 기반 Event Loop 설명이 많은데 백앤드 입장 Event Loop를 정리해 본다.

    브라우저 기반 Event Loop 설명은 아마 80%가 아래의 8년 전 영상이 출처인 것으로 보인다. (설명을 굉장히 잘한다.)
     
    - JS Conf 브라우저의 이벤트 루프 : https://www.youtube.com/watch?v=8aGhZQkoFbQ 
     

    사전 지식 :  병렬성과 동시성

    Event Loop를 이해하기 위해서는 동시성(concurrency)과 병렬성(parallelism) 이해가 선행되야 한다. 

    • 자바로 예를 들면 스프링부트로 서버를 띄우면 톰캣에 기본 max 200개 thread가 생성되도록 되어있다.
    • 200개의 멀티쓰레드로 동시에 병렬로 CPU에게 작업을 요청할 수 있다. 
    • 자바에서는 멀티스레딩으로 병렬성을 Locking/Unlocking으로 동시 요청에 대한 문제를 해결한다.
      • 병렬 = 한 번에 여러 일을 동시에 처리한다. race condition 문제가 발생할 수 있다. (대표적으로 데드락, 정합성)
    한번에 4개의 task를 병렬로 작업 이미지
    • 자바스크립트는 싱글스레드 기반으로 하나의 스레드에서 하나의 일을 세부 task로 나눠서 동시에 번갈아가면서 처리한다.
    • file I/O, network 등은 데이터를 get 해서 메모리에 담기 전까진 CPU가 아닌 다른 하드디스크에서 처리한다.
    • 메모리에 담기 전까진 CPU가 다른 일을 할 수 있다. CPU가 일이 끝나면 Queue에 쌓인 Task를 감지하여 일을 하는 방식으로 동시성으로 동작 (이것을 Non Blocking I/O라 한다.)
      • 동시성 문제는 sub task1과 sub task2가 shared data에 동시에 접근했을 때 문제가 발생한다
    Task 1개를 여러 작업으로 나눠서 실행

    이벤트 루프란?

    • [위키피디아] 이벤트 루프는 프로그래밍의 이벤트나 메시지를 대기하다가 디스패치(dispatch란? 프로세스가 CPU를 점유하는 것 준비→실행 상태로 바꾸는 것)하는 프로그래밍 구조체이다.
    • CPU가 일이 끝나면 Queue에 쌓인 Task를 감지하는 것을 이벤트를 기반으로 동시성을 해결한 프로그래핑 패턴이다. (Reactor 패턴, 멀티 플랙싱 같은 방식도 있는 거 같다.)
    • 이벤트 루프는 작업이 있는지 모니터링(polling loop)하거나, 무언가에 의해 Trigger, 또는 blocks을 통해 동시성 문제를 해결한다.
    • JS에서 이벤트 루프(Event loop)는 callback queue와 call stack을 모니터링하고 지속적으로 실행되는 프로세스.
    • Spring WebFlux도 이벤트 루프를 기반으로 동작한다. 
    출처 - 인프런 : Kevin의 리액티브 프로그래밍 블로그

    Node JS에서 Event Loop란 무엇인가

    브라우저 기반 call stack, webApi, task queue 이런 거 말고 Node js에서 이벤트 루프가 뭔지 살펴보자.
    Callback 함수를 모르는 분이라면 생활코딩 참고
    아래 글은 https://www.voidcanvas.com/nodejs-event-loop/ 페이지를 번역했다.
     

    • 아래의 그림은 Node JS 아키텍처이다.
      • 각 페이즈마다 Queue 작업을 할 수 있다. (즉 Node Js는 하나가 아니라 여러 개의 callback queue가 단계별로 있다.)
      • nextTickQueue, microTaskQueue 두 가지는 이벤트 루프에 속하지 않고, 어떤 페이즈에서든 실행할 수 있다. 콜백에서 우선순위가 가장 높다. 
      • Callback은 FIFO으로 동작
      • Node js의 이벤트 루프는 libuv 패키지에 위치한다.
       
    Node Js 아키텍처

     

    • Timer
      • 이벤트 루프의 시작단계
      • setTimeout, setInterval과 같은 콜백이 보관한다.
      • callback을 queue에 푸시하지 않고, timer가 최소 힙 유지하고 시간 경과하면 콜백 실행
    • Pending I/O callbacks
      • pending_queue에 있는 콜백 실행.
      • 이전 작업에서 pushed 된 작업.
    • Idle, prepare (노드 내부 작업)
      • idle은 매 tick에 실행된다.
      • prepare는 polling 전 매번 실행된다.
    • Poll
      • 이벤트 루프에 가장 중요한 단계
      • 새 커넥션을 받아 대기열 큐에 보낸다. (ex, 소켓 연결, 파일 읽기)
      • watch_queue(대기열)에 작업이 있으면 동기적으로 수행한다.
      • 대기열이 empty 하면 다른 새 커넥션을 기다린다.
    • Check
      • setImmediate() 콜백의 전용 단계
      • poll을 위해 setImmediate()만 따로 작업
    • Close callbacks
      • cleanup 단계
    • nextTickQueue & microTaskQueue
      • C/C++ ~ JavaScript 넘을 때마다 가능한 한 빨리 호출된다.
      • nextTickQueue는 api process.nextTick()로 콜백 보관
      • microTaskQueue는 Promise resolved 한 작업 콜백 보관

    Event Loop Work Flow

    출처 : F-lab 홈페이지 - 노드 개발자는 이런 질문을 받는다고 한다.

    Reference

    반응형
Designed by Tistory.