본문 바로가기
JS

Node.js 공식 홈페이지 방문

by kicksky 2021. 5. 11.

면접 준비하는 김에 계속 미뤄왔던 Node.js를 알아보기로 했다. 몇달 전 <노드 디자인 패턴> 1장을 읽으면서 머리를 쥐어뜯은 이후로 오랜만. 공식 홈페이지부터 순회했다.

Node.js

"비동기 이벤트 주도(asynchronous event-driven) JavaScript 런타임으로써 Node.js 는 확장성 있는 네트워크 애플리케이션(scalable network application)을 만들 수 있도록 설계"되었다. "이는 오늘날 OS 스레드가 일반적으로 사용하는 동시성 모델과는 대조적"이다. "스레드 기반의 네트워크(Thread-based networking)는 상대적으로 비효율적이고 사용하기가 몹시 어렵"다고 한다.

- Node.js의 가장 큰 특징은 동시성 모델을 따르지 않는, 비동기 이벤트 주도 JS 런타임이라는 것 같다. OS thread는 multi인 반면, Node.js는 single thread 기반이기 때문? 이 부분을 명확히 이해하려면 스레드와 프로세스를 마저 공부해야할 것 같다. 운영체제 강의 다시 들어야할 듯.

더 나아가 잠기는 부분(locks)이 없으므로 Node.js 의 사용자는 프로세스의 교착상태(dead-locking)에 대해서 걱정할 필요가 없습니다. Node.js 에서 I/O를 직접 수행하는 함수는 거의 없으므로 프로세스는 블로킹 되지 않습니다. 아무것도 블로킹 되지 않으므로 Node.js 에서는 확장성 있는(scalable) 시스템을 개발하는 게 아주 자연스럽습니다.

- 블로킹과 확장성 있는 시스템의 관련성? 아, 오리발처럼 이것 저것 갖다 붙여도 중간에 먹통될 일이 없어서 확장성이 좋다고 하는 것 같다. 

이벤트 루프는 라이브러리가 아닌 런타임 생성자다. 다른 시스템에서는 이벤트 루프를 시작하는 블로킹 호출이 항상 존재합니다. 그러나 Node.js는 이벤트 루프를 시작하는 호출이 없고, 입력(I) 스크립트를 실행한 후에 이벤트 루프에 바로 진입합니다. 그리고 더 이상 실행할 콜백이 없으면 이벤트 루프를 종료합니다. 이 동작은 브라우저 JavaScript과 유사하며, 사용자에게서 이벤트 루프를 감춘다. 

- Node.js는 따로 이벤트 루프를 시작하는 블로킹 호출 없이 바로 진입하고 실행할 콜백이 없을 때 알아서 종료한다. 

HTTP는 일급 객체(first class citizen)이고 스트리밍과 저지연을 염두에 두고 설계되었으므로 Node.js는 웹 라이브러리나 프레임워크의 기반으로 아주 적합하다.

*일급 객체: first-class citizen (also typeobjectentity, or value). "다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 가리킨다. 보통 함수에 매개변수로 넘기기, 수정하기, 변수에 대입하기와 같은 연산을 지원할 때 일급 객체"


Overview of Blocking vs Non-Blocking

"I/O"는 주로 libuv가 지원하는 시스템 디스크나 네트워크와 상호작용하는 것을 가리킨다. "I/O" refers primarily to interaction with the system's disk and network supported by libuv. ("a multi-platform support library with a focus on asynchronous I/O.")

- I/O 작업을 OS나 libuv가 수행한다는 의미. 예전에 노드 디자인 패턴이라는 책 읽을 때는 저 libuv가 뭔가 대단한 첨단 기술인 줄 알았는데 그 정도까지는 아니고 C++로 작성된 라이브러리였음.

블로킹은 Node.js 프로세스에서 추가적인 JavaScript의 실행을 위해 JavaScript가 아닌 작업이 완료될 때까지 기다려야만 하는 상황을 의미한다. 이벤트 루프가 블로킹 작업을 하는 동안 JavaScript 실행을 계속할 수 없기 때문. libuv를 사용하는 Node.js 표준 라이브러리의 동기 메서드가 가장 대표적인 블로킹 작업입니다. 네이티브 모듈도 블로킹 메서드를 가질 수 있습니다. Node.js 표준 라이브러리의 모든 I/O 메서드는 논블로킹인 비동기 방식을 제공하고 콜백 함수를 받습니다. 일부 메서드는 같은 작업을 하는 블로킹 메서드도 가지는데 이는 이름 마지막에 Sync가 붙습니다.

CPU 집약적인 작업 때문에 나쁜 성능을 보여주는 JavaScript는 보통 블로킹이라고 부르지 않는다.

동시성과 스루풋

Node.js에서 JavaScript 실행이 싱글 스레드이므로 동시성은 다른 작업이 완료된 후에 JavaScript 콜백 함수를 실행하는 이벤트 루프의 능력을 의미. 동시에 실행되어야 하는 모든 코드는 I/O 등의 JavaScript가 아닌 작업이 일어나는 동안 이벤트 루프가 계속 실행될 수 있도록 해야 합니다.

- 예전에 노드로 서버 코드 짤 때,  어떤 '순차적' 흐름이라는 막연한 개념만 알고 있어서 await 남용했었다. 동기, 비동기 확실하게 알고 있었으면 더 효율적으로 코드를 작성할 수 있었을텐데. 그런데 사실 그 때도 이렇게 DB를 쿼리로 들락날락하는 게 맞는 건가하고 계속 고민은 했었다. 그렇다고 딱히 해법이 될 키워드를 알고 있어서 방법들을 찾아볼 수 있는 실력은 안되는 바람에 우선 굴러가니 OK였을 뿐


 

'JS' 카테고리의 다른 글

[TIL] Promise, async/await  (2) 2022.06.12
Class: constructor에서 async await  (0) 2021.03.08
배열 Array: 루프  (0) 2021.03.08
중첩된 async await  (0) 2021.03.08
Fetch API  (0) 2021.03.05

댓글