Node.js란?

Node.js란 자바스크립트 런타임 환경 및 라이브러리 입니다. 서버 측 웹 응용 프로그램을 만드는 데 사용됩니다.

자바스크립트 런타임

이제는 JS가 컴파일, 인터프리터 언어라고 할 수 없다. 왜냐하면 엔진에 따라 다르기도 하고, 컴파일과 인터프리터 둘다 쓰이기도 한다.

노드는 자바스크립트 런타임이다. 런타임은 특정 언어로 만든 프로그램들을 실행할 수 있는 환경을 뜻합니다.

노드는 v8과 더불어 libuv라는 라이브러리를 사용합니다.

libuv 라이브러리는 노드의 특성인 이벤트 기반, 논블로킹 I/O 모델을 구현하고 있습니다. 노드는 스스로를 이벤트 기반, 논블로킹 I/O 모델을 사용해 가볍고 효율적이라고 표현했다.

이벤트 기반

이벤트가 발생할 때 미리 지정 해둔 작업을 수행하는 방식을 의미합니다. 이벤트로는 클릭이나 네트워크 요청 등이 있을 수 있습니다.

이벤트 기반 시스템에서는 특정 이벤트가 발생할 때 무엇을 할지 미리 등록해두어야 합니다. 이것을 이벤트 리스너에 콜백 함수를 등록한다교 표현합니다.

ex) spring bean라는 객체를 만들어서 관리를 해줌.

여러 이벤트가 동시에 발생했을 때 어떤 순서로 콜백 함수를 호출할지를 이벤트루프가 판단합니다.

그냥 콜 스택에 쌓이는 함수들은 쉽게 출력이 예측되지만 setTime함수를 쓰게되면 인터프리터 언어이기 때문에 js가 호출 타이밍을 알기 어렵다.

  • 이벤트 루프: 이벤트 발생 시 호출할 콜백 함수들을 관리하고, 호출된 콜백 함수의 실행 순서를 결정하는 역할을 담당한다. 노드가 종료될 때 까지 이벤트 처리를 위한 작업을 반복하므로 루프라고 불린다.
  • 태스크 큐(이벤트 큐): 이벤트 발생 후 호출되어야 할 콜백 함수들이 기다리는 공간입니다. 콜백들이 이벤트 루프가 정한 순서대로 줄을 서 있으므로 콜백 큐라고도 불립니다.
  • 백그라운드: 타이머나 I/O 작업 콜백 또는 이벤트 리스너들이 대기하는 곳 입니다.

  1. 호출 스택에 쌓임
  2. setTimeout 실행 시 콜백 run은 백그라운드로
  3. 백그라운드에서 3초 후 태스크 큐로 보냄
  4. 호출 스택 실행이 끝나 비워지면
  5. 이벤트 루프가 태스크 큐의 콜백을 호출 스택으로 올림
  6. run이 호출 스택에서 실행되고 비워짐
  7. 이벤트 루프는 태스크 큐에 콜백이 들어올 때 까지 대기

만약 호출 스택에 함수들이 너무 많이 차 있으면 3초가 지난 후에도 run 함수가 실행되지 않을 수도 있다. 이벤트 루프는 호출 스택이 비어 있을 떄만 태스크 큐에 있는 run 함수를 호출 스택으로 가져온다. 이것이 setTimeout의 시간이 정확하지 않을 수도 있는 이유입니다.

논블로킹 I/O

이전 작업이 완료될 때 까지 멈추지 않고 다음 작업을 수행함

이벤트 루프를 잘 활용하면 오래 걸리는 작업을 효율적으로 처리할 수 있다.

  1. 오래걸리는 함수를 백그라운드로 보내서 다음 코드가 먼저 실행되게 하고
  2. 그 함수가 다시 태스트 큐를 거쳐 호출 스택으로 올라오기를 기다리는 방식

블로킹보다 논블로킹 방식이 같은 작업을 더 짧은 시간 동안 처리할 수 있음을 알 수 있지만 싱글스레드라는 한계 때문에 자바스크립트의 모든 코드가 이 방식으로 시간적 이득을 볼 수 있는 것은 아니다.

노드 프로세스외의 다른 컴퓨팅 지원을 사용할 수 있는 I/O작업이 주로 시간적 이득을 많이 본다.

싱글 스레드

자바스크립트와 노드에서 논블로킹이 중요한 이유는 바로 싱글 스레드이기 때문이다. 한 번에 한 가지 일밖에 처리하지 못하므로 어떠한 작업에서 블로킹이 발생하면 다음 일을 처리하지 못한다.

언뜻 보면 여러 개의 일을 동시에 처리할 수 있기 때문에 멀티 스레드가 싱글 스레드보다 좋아 보인다. 하지만 꼭 그런 것만은 아니다.

노드는 스레드를 늘리는 대신, 프로세스 자체를 복사해 여러 작업을 동시에 처리하는 멀티 프로세싱 방식을 택했다.


Reference