아래는 Node.js 내부에서 libuv가 담당하는 역할에 대해 자세하게 설명한 내용입니다.
libuv는 Node.js의 핵심 라이브러리 중 하나로, 여러 운영체제(OS)에서 비동기 I/O와 이벤트 기반 프로그래밍을 지원하는 플랫폼 독립적인 추상화 계층 역할을 합니다. 이를 통해 Node.js는 단일 스레드 모델에서도 높은 동시성을 유지할 수 있으며, 다양한 시스템 자원과 작업을 효율적으로 처리할 수 있습니다.
이벤트 루프의 핵심:
Node.js의 이벤트 루프는 libuv에 의해 구현됩니다. 이벤트 루프는 여러 단계(phase)로 구성되어 있으며, 각 단계는 특정 작업들을 처리합니다.
주요 단계 및 libuv의 역할: → 이 내용은 앞으로 Node.js 개발자가 되기위해서는 반드시 기억하고 있는 것이 좋습니다.
타이머(Timers) 단계:
setTimeout()
이나 setInterval()
에서 예약된 타이머 콜백을 실행합니다. libuv는 OS 타이머 API를 사용해 정확한 시간에 콜백을 스케줄링합니다.
I/O 콜백(Pending Callbacks) 단계:
일부 시스템 I/O 호출의 결과를 처리하는 콜백들이 이 단계에서 실행됩니다.
Poll 단계:
실제 I/O 이벤트(네트워크, 파일 시스템 등)를 기다리고, 발생한 이벤트의 콜백을 실행합니다. libuv는 epoll, kqueue, IOCP 등의 메커니즘을 사용해 이벤트를 감지합니다.
Check 단계:
setImmediate()
콜백을 처리합니다. libuv는 이 단계에서 즉시 실행되어야 하는 콜백들을 빠르게 실행할 수 있도록 큐를 관리합니다.
Close Callbacks 단계:
소켓, 파일 핸들 등의 종료(close) 이벤트와 관련된 콜백을 실행합니다.
큐와 스케줄링:
libuv는 각 단계마다 내부 큐를 관리하며, 이벤트 루프 주기 내에서 순차적으로 각 단계의 작업을 실행합니다.
비동기 작업의 분산 처리:
Node.js는 일부 I/O 작업(특히 파일 시스템 작업, DNS 조회, 암호화, 압축 등)이 비동기 API로 처리되지 않거나, CPU 집약적인 작업일 경우, libuv의 스레드 풀을 사용합니다.
스레드 풀의 역할:
타이머 관리:
libuv는 OS의 타이머 기능을 활용하여, 타이머 기반 콜백을 정확한 시점에 실행합니다.