1장: Reactor 패턴 (내용 검증 필요)

1장은 Node.js에 대한 소개하는 챕터이다.


주의!
해당 글의 내용은 부정확한 내용이 아주 많을 수 있습니다. 책의 설명이 추상적이고 OS 개념이 많이 필요하므로 추후 정리가 완료되는 경우 따로 표시하겠습니다.


Node.js 철학 (Node Way)

최소 기능: 기능 개수를 최소한되므로, 개발자, 사용자 모두에게 간단함

  1. Node.js 자체 뿐만 아니라 node 기반 모듈을 설계할 때도 동일하게 적용
  2. KISS 원칙: 부족하더라도 복잡함보다 단순함이 더 낫다

Reactor 패턴과 Node.js 이벤트 루프

Reactor 패턴은 Node.js의 비동기 특성 - Node.js에서 여러 요청이 동시에 있는 경우는 항상 비동기 방식으로 작업을 처리한다 - 의 원인이자, 비동기 방식으로 작업을 처리하는 방법에 해당한다. Reactor 패턴을 배우기 전에, 동시성을 처리하는 2가지 방법에 대해서 알아보자.

Blocking I/O : 느린 I/O기다리는 방식

  1. 많은 스레드 개수: 소켓의 데이터를 매번 기다리게 되면 각 연결 별로 스레드가 적어도 하나씩 돌아야 한다. 기다리는 시간에 타 사용자가 기다리지 않게 하기 위해서이다.

  2. 비효율적인 대기 시간: I/O가 CPU에 비해 매우 느리기 때문에 블로킹 API는 스레드의 유휴 시간이 처리 시간에 비해 압도적으로 길 수 밖에 없다. 스레드가 아무 일을 하지 않은 상태로 긴 시간 존재한다.

  3. 스레드의 비용: 스레드는 그 비용이 싸지 않다. 아주 많은 스레드가 있는 경우, Context Switching만 해도 비용이 매우 클 것이고, 적은 스레드가 있는 경우 사용자를 처리하지 못하므로 비즈니스적으로 비용이 매우 클 것이다.

Non-blocking I/O: 비동기 API를 호출 시 바로 제어권을 반환(내부적으로 특정 상수를 반환)하여 CPU 유휴 시간을 최소화한다.

  1. Polling: 비효율적으로 I/O를 처리하는 방식으로, 리소스는 데이터가 없을 때 읽기 조작을 요청 받는 경우 EAGAIN을 반환하는데, 이 때문에 값이 필요한 입장에선 리소스를 계속 확인해야 한다. 이걸 BUSY_WAITING이라고 하는데, CPU를 계속 활용하므로 효율적이지 못하다.

  2. 동기 이벤트 디멀티플렉서: 논블로킹을 처리하는 효율적인 방법으로, 이벤트가 완료될 때마다 큐에 이벤트를 쌓아놓고 처리를 수행하는 객체. 이벤트가 없으면 Block 상태로 대기한다.

    1. 이벤트 통지자가 감시 대상 리소스의 자원이 읽기가 가능할 때(즉, 이벤트가 완료되었을 때) Demultiplexer에게 통지한다. (이벤트 통지자 역할로 IOCP, epoll/kqueue 등이 있는 것 같다.)

    2. Event가 발생하면 Event Demultiplexer가 깨어나 Queue에서 이벤트를 읽어들여 처리하면 됨. 이 시점에서 리소스의 I/O 작업은 (1)에서 이미 완료되어있으므로 동기식으로 처리하면 됨. 또한 처리 방식이 싱글 스레드이므로 공유 자원 문제도 존재하지 않는다.

리액터 패턴: 이벤트 디멀티플렉서 + 이벤트 루프 + 이벤트 큐 + 실행 환경(V8, 싱글 스레드!)

  1. 이벤트 디멀티플렉서는 I/O 처리가 끝나면 (완료된) 이벤트를 이벤트 큐에 넣어줌

  2. 이벤트 루프는 실행 환경 상에서 스택이 비는 경우(즉 모든 동기 코드가 실행이 끝났을 때 - 노드 환경에서 동기 코드는 얼마 없어서 최초의 동기 코드는 금방 끝나기 마련.), 이벤트 큐에서 이벤트를 꺼내어 실행 환경에 이벤트 핸들러를 올리고, 인자로 이벤트를 넘겨 수행함.

    1. 만약 async 내에 async가 있다면 해당 이벤트는 또 이 과정을 거침.

이벤트 디멀티플렉서의 구현체

libuv: 크로스 플랫폼으로(가상머신 느낌으로 각 OS에 대응되는 이벤트 통지자를 활용) 비동기 작업을 처리함. 단, libuv는 이벤트 디멀티플렉서 역할만 하는 게 아니라 이벤트 루프도 구현함.

참고: libuv에 이벤트루프가 포함돼있음:

더 정확한 이벤트 디멀티플렉서, 이벤트 루프 구현 상세에 관한 글, 영상

로우 레벨로 살펴보는 Node.js 이벤트 루프 | Evans Library

Node.js 이벤트 루프, 타이머, process.nextTick() | Node.js (놀랍게도 이 문서가 더 어려운 것 같다…)

브라우저 환경에서의 이벤트 루프(자막 있음, 자세함!):
Jake Archibald: In The Loop | JSConf.Asia

아마도 이벤트 루프에 대한 가장 유명하고, 쉬운 설명:
What the heck is the event loop anyway? | JSConf EU


1장: Reactor 패턴 (내용 검증 필요)

https://jsqna.com/ndp-1-reactor-pattern/

Author

Seongbin Kim

Posted on

20-12-27

Updated on

21-01-19

Licensed under

댓글