Node Way
be Smaller and be Simple
lightweight Core
Node Core의 기능을 최소화하고, 방대한 사용자 전용 모듈 생태계 ( User Land ) 를 구축했다.
사용자 관점에서 폭 넓은 해결책을 실험해 볼 수 있게 됐다. ( 모듈 생태계가 매우 크게 형성돼있다. )
lightweight Module
Node Code 구성의 기본단위는 Module이다.
최대한 Minimal 하고, 하나의 단일 기능만 가지도록 디자인하는 패턴이 있으며 모듈들이 상호의존하며 생태계를 구성하고 있기 때문에 NPM을 이용해 해결한다.
합리적이며, 테스트와 리팩토링이 용이하다.
Small Interface
명백한 단일 진입점을 위한 단 하나의 함수/클래스를 노출시킨다.
이때 Class는 내부 메소드에 따라 단일 진입이 아니게 될 수 있으므로 Function 노출을 선호한다.
정리
??? : Keep It Simple, Stupid. Do KISS
Internal workings of Node.js
Tradition
Blocking I/O의 사용시 Locked Thread가 발생한다.
그에 따라 동시 연결 시 더 많은 양의 Thread가 필요하다.
Thread는 적은 자원을 소모하는 작업이 절때 아니기 때문에 ( Memory space, Context Swtich ... ) I/O 작업을 위해 많은 CPU 자원을 필요로 한다.
Now -> Non-Blocking
- Poll ( Busy Waiting ) : Consumable Data가 있을 때까지 Polling한다. 사용할 수 없는 리소스 참조를 지속 반복하기 때문에 CPU 비용이 많이 사용된다.
- Sync. Event De-Multiplexing : 여러 리소스를 관찰하고 리소스가 사용됐을 때 새로운 이벤트를 반환한다. Poll과 다른 점은 새로운 이벤트가 생기기 전까지 Blocking된다는 점.
De-Multiplexer가 처리할 Event Sets를 주기 전까지 블록킹되는 실행 흐름을 Event-Loop라 한다. 이 덕분에 여러 I/O 작업을 Single Thread로 처리할 수 있다.
Node Core ( Reactor Pattern )
App은 특정 시점에 Non-Blocking으로 Event Demultiplexer에 Resource Access Request를 Callback과 함께 Passing한다.
Operation
1. 서로 다른 유형의 자원에 대한 Non-Blocking Operation의 표준화를 위해 libuv라는 C 라이브러리가 필요
4. Event Loop는 CallBack Function을 처리하기 위해 Handler에게 제어건을 건내주고 Handler는 작업이 완료되면 바로 제어권을 넘겨주거나 (5a) 또다른 I/O 요청이 필요하면 Non-Blocking으로 Request한다. (5b)
ASync. VS Non-Blocking
Async & Sync: 어떠한 Flow로 전체 작업을 처리할 것인가
Block & Non-Block: 처리해야 할 작업이 전체 Flow를 막느냐 막지 않느냐
Async / Non-Blocking
- Main Thread가 원할 때 I/O 작업을 요청 후 작업 권한을 작업 Thread에 뺏기지 않음 ( 비동기 )
- 작업 Thread가 작업할 때 전체 Flow ( Main Thread )를 막지 않음 ( 논블록킹 )
Sync
- Main thread가 원한 작업이 끝날 때 까지 대기 ( 동기 )
- 이미 동기로 전체 Flow가 막히기 때문에 논블록킹/블록킹은 의미가 없음
Async / Blocking
- Main Thread가 원하는 작업을 맞긴 후 도망치려 하지만 ( 비동기 ) 작업 Thread가 이를 놔주지 않음 ( 블록킹 )
How is it possible to execute async jobs in Node.js, which has only one thread?
Node는 I/O
작업을 자신의 메인 스레드가 아니라 다른 스레드에 위임함으로 싱글 스레드로 논블로킹 비동기 작업을 지원할 수 있게 되는 것이다. 즉 Node는 I/O
작업을 libuv
에 위임함으로 논블로킹 비동기 작업을 지원한다.
운영체제를 추상화 하였기 때문에 libuv
는 Node에서 처리하고자 하는 비동기 작업이 운영체제에서 지원을 하는 것인지, 지원하는 것이 아닌지 판단이 가능하다.
그렇기 때문에 비동기 작업 요청이 들어왔을 때 아래와 같이 처리를 하게 된다.
if (운영체제에서 지원하는 비동기 작업) {
libuv가 대신 커널에 비동기로 요청을 했다가 응답이 오면 응답을 전달해준다.
(응답이 전달될 때는 OS가 systemcall을 통해 callback이 이벤트 루프에 등록.)
} else {
워커 쓰레드가 담긴 자신만의 쓰레드 풀을 이용하여 작업을 처리
}
출처 : Node는 어떻게 비동기를 처리할까?
출처 : Node.js 디자인 패턴 바이블
'Backend > Node.js' 카테고리의 다른 글
비동기 흐름 제어 by Callback (0) | 2025.01.06 |
---|---|
Observer 패턴 (0) | 2025.01.06 |
Callback 패턴 (0) | 2025.01.06 |
Module System ( ESM ) (0) | 2025.01.06 |
Module System ( CJS ) (0) | 2025.01.06 |