Node.js의 동작 원리를 알기 위해서는 javascript의 동작원리를 먼저 알아야 한다.
자바스크립트 동작원리
Node.js란?
- JavaScript를 브라우저 밖에서도 실행시킬 수 있는 JavaScript 런타임
- 싱글 스레드 논블로킹 모델
- 싱글 스레드지만 비동기 I / O 작업을 통해 요청들을 서로 블로킹하지 ❌
- 동시에 많은 요청들을 비동기로 수행함으로써 싱글 스레드일지라도 논블로킹이 가능하다.
- 이벤트 기반으로 동작한다.
- 이벤트 기반이란? 이벤트가 발생할 때 미리 지정해둔 작업을 처리하는 방식
⇒ NodeJS는 이벤트 리스너에 등록해둔 콜백 함수를 실행하는 방식으로 동작한다.
⇒ 이벤트 루프가 이를 가능하게 해줌.
- 클러스트링을 통해 프로세스를 포크하여 멀티 스레드처럼 사용할 수 있다.
01. 동기(Sync) VS 비동기(Async)
처리해야 할 작업들에 대한 처리과정
-
동기 (Synchronous)
- 작업 A의 종료시간과 작업 B의 시작시간이 같으면 동기적이라고 한다.
-
비동기 (Asynchronous)
- 작업 A와 B가 서로의 시작, 종료 시간과는 관계 없이 별도의 수행 시작/종료시간을 가지는 것을 말한다.
02. 싱글 스레드 VS 멀티 스레드
- 싱글 스레드
- 프로세스 내에서 하나의 스레드가 하나의 요청만을 수행하는 것
- 한 번에 여러 요청을 수행할 수 없다.
- 블로킹 모델
- 멀티 스레드
- 스레드 풀에서 실행의 요청만큼 스레드를 매칭하여 작업을 수행하는 것
- 논블로킹 모델
03. 블로킹(Blocking) VS 논블로킹(Non-Blocking)
처리해야 할 작업의 과정을 막는가? 막지 않는가?
-
Blocking
- 직접 제어할 수 없는 작업이 끝날 때까지 기다려야 하는 경우
- 호출된 함수에서 I/O 작업 등을 요청했을 경우 I/O 작업이 처리되기 전까지 아무일도 하지 못한다.
-
Non-Blocking
- 직접 제어할 수 없는 작업이 완료되기 전에 제어권을 넘겨주는 경우
- 호출된 함수에서 I/O작업등을 요청했을 경우 I/O작업의 처리여부와 관계없이 바로 다음 작업을 할 수 있다.
Node.js 내부 구조
- 내장 라이브러리
- V8 엔진
- libuv
- Node.js에서 사용하는 비동기
I/O
라이브러리
- Node.js의 특성인 이벤트 기반, 논 블로킹
I/O
모델들은 모두 libuv 라이브러리에서 구현된다.
- 콜백 함수들은 libuv 내에 위치한 이벤트 루프에서 관리 및 처리된다.
논블로킹 I / O
- Input Output이 관련된 작업(데이터베이스 CRUD, 파일 시스템)등의 블로킹 작업들은 백그라운드에서 수행하고 이를 비동기 콜백 함수로 이벤트 루프에 전달하는 것
I/O
작업들은 OS 커널 혹은 libuv 내의 스레드 풀에서 담당하게 된다.
- libuv의 스레드풀은 커널이 지원 안하는 작업들을 수행한다.
libuv의 동작방식
- Node.js는 기본적으로 libuv 위에서 동작하여 node 인스턴스가 생성될 때 libuv에는 스레드 풀이 (기본값은 4개의 스레드)가 생성된다.
- libuv는 OS 커널이 어떤 비동기 작업들을 지원해주는지 알고 있다.
→ libuv의 스레드는 커널이 지원하지 않는 작업들을 수행한다.
참고자료