본문 바로가기
Nest

[Nest] NodeJs Event Loop

by chu_dw 2024. 1. 26.

앞 글에서 정리한 듯이 일반적으로 싱글 스레드로는 nonblocking으로 작업 처리가 어렵다.

 

그럼 과연 node는 어떻게 싱글 스레드 기반으로 논블로킹을 제공할까?

결론부터 말하자면 nodejs는 여러 비동기 작업을 위한 구현체인 Event Loop를 통해 논블로킹을 제공한다.

 

nodejs 구조

 nodejs의 구조이다.

저번 글에 v8엔진은 간단히 정리하였고 못 보던 libuv가 있다.

이것이 node에 비동기를 비동기 I/O 라이브러리 이다.

 

 

libuv란?

조금 더 사전적으로 정의하면

비동기 I/O를 지원하는 C언어 Library로 윈도우, 리눅스 커널을 Wrapping 하여 추상화한 구조로 되어있다.

커널의 비동기 API (윈도우- IOCP, 리눅스-AIO) 로 지원할 수 없는 작업을 비동기화 하기 위한

별도의 Thread Pool을 가지고 있고 Event Loop, Event Queue를 관리한다.

 

 

논블로킹과 비동기

여기서 가장 헷갈리는 부분이 nonblocking vs 비동기이다

일단 이전에 내가 이해하기론 node는 eventloop를 통해 싱글스레드 지만 nonblocking을 제공한다였다.

그런데 찾아보니 eventloop를 통해 비동기 처리를 한다고 한다. (그럼 둘 중 뭘 위한거?)

다시 정리해 보면 nodejs는 이벤트 루프를 통해 비동기 처리를 하면서도 논블로킹 모델을 구현하여

효율적으로 다수의 동시 연결을 다루고 응답성을 향상시킨다 이다.

 

계속 블로킹 논블로킹, 동기 비동기 헷갈려서 글을 하나 따로 정리하도록 하겠다.

 

 

libuv 역할

libuv에 대해서 더 자세히 정리해보겠다.

위에서 말했듯이 libuv는 별도의 스레드 풀을 가지고 있고 이 스레드 풀은 기본적으로 4개의 스레드를 가진다.

비동기 처리를 요청받게 되면 libuv는 이 스레드 풀에게 작업을 맡기고 작업이 완료되면 완료 응답을 리턴한다.

(커널에서 지원 가능한 비동기 처리는 libuv가 커널에 맡긴 후 응답을 전달해 준다.)

이걸 정리해 보면 node는 싱글스레드이지만 I/O작업을 libuv로 위임 함으로 논블로킹 비동기를 지원하고

그 기반에는 eventloop가 있다

 

 

그래서 singlie Thread?

하지만 의문이 남는다. 결국엔 libuv안에 스레드가 여러 개 있는데 싱글스레드가 맞는가?

nodejs가 싱글 스레드로 동작한다는 것은 javascript 코드가 하나의 스레드에서 실행됨을 의미한다.

이 하나의 메인 스레드는 libuv 통해 비동기 작업을 실행하는데,

libuv의 스레드 풀은 메인 스레드와 별도로 동작하고 작업이 완료되면 해당작업의 콜백함수를 실행한다.

그럼 메인 스레드에서 완료된 콜백함수를 실행시킨다.

이때는 메인 스레드인 싱글스레드로 완료된 순서대로 실행되고

(이것이 시작순서와 상관없이 비동기로 진행되는 것이다.?)

 

nodejs가 메인 스레드 + libuv 스레드 풀 이렇게 별도로 가지고 있는 것은 아니고 

메인 스레드 안에서 event loop이 실행되며 비동기 작업이 수행되도록 돕는 것이다.

 

 

event loop 구성

그럼 libuv의 기반이 되는 event loop을 정리하겠다.

위에서 간단히 설명했듯이 여러 비동기 작업을 관리하기 위한 구현체인 event loop은 아래 단계로 진행된다.

이벤트 루프는 위의 페이즈(timer, pending i/o, close callback, check 등)를 순회하며 각 단계에서

발생한 이벤트를 처리하고 이벤트 큐에 있는 작업들을 실행시켜 작업을 완료한다. 

 

- timer phase : 설정된 시간이 경과한 타이머 이벤트가 처리

- pending i/o callback phase : 비동기 i/o 작업의 콜백 함수들이 실행

- idel, prepare phase : 대기 상태와 준비 상태 나타냄

- poll phase : 이벤트 큐에서 이벤트를 가져와 처리

- check phase : 이벤트 루프가 실행을 마칠 때까지 대기하는 setimmdiate 처리

- close callbacks phase : 자원이 닫히거나 소캣이 닫힐 때 실행되는 콜백함수들 처리

 

- nextTick 큐 : 다른 이벤트 루프의 단계를 기다리지 않고, 현재 실행 중인 코드 블록이 끝날 때마다 즉시 실행

- microtask 큐 : promise로 등록된 task들이 대기하는 큐, 현재단계에서 모든 task 처리 후 다음 단계

 

 

 

 

 

 

https://medium.com/zigbang/nodejs-event-loop%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-16e9290f2b30

 

NodeJS Event Loop파헤치기

안녕하세요! 직방 서비스개발그룹 백엔드팀 아파트파트에서 근무중인 김범준입니다. 이번 포스팅에서는 NodeJS의 Event Loop에 대한 내용을 정리해보려 합니다. 그럼 같이 시작해 볼까요?

medium.com

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

 

Node.js 이벤트 루프(Event Loop) 샅샅이 분석하기

Node.js의 이벤트 루프를 구현과 함께 자세히 살펴봅니다

www.korecmblog.com

https://velog.io/@dev_leewoooo/Node%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%85%BC-%EB%B8%94%EB%A1%9C%ED%82%B9%EC%9D%84-%EC%A7%80%EC%9B%90%ED%95%A0%EA%B9%8C-with-Eventloop

 

Node는 어떻게 논 블로킹을 지원할까 (with Eventloop)

Node의 비동기 작업을 지원하는 Eventloop에 대해 알아보자 :)

velog.io

 

'Nest' 카테고리의 다른 글

[Nest] nest guard  (0) 2024.02.29
[Nest] 데코레이터, 메타데이터  (0) 2024.02.26
[Nest] NestJs 구조  (0) 2024.01.29
[Nest] Node.js 특징 (single Thread, Nonblocking)  (0) 2024.01.15
[NestJS] NestJs란?  (0) 2024.01.14