TIL 029 | Node.js

Node.js 란

Node.js 를 정의하자면, 비동기(Asynchronous) 이벤트-기반(event-driven) JavaScript 런타임 환경이다. Node.js 는 웹브라우저에 종속적인 자바스크립트를 외부에서 실행할 수 있는 Runtime 환경인 Chrome V8 엔진을 제공하여 여러 OS 에서 실행할 수 있는 환경을 제공해준다.


비동기 이벤트-기반

노드 입장에서 이벤트는 프론트엔드(클라이언트)에서 받는 요청이다.

노드가 비동기적으로 이벤트를 처리한다는 것은 앞선 클라이언트의 요청이 끝나기 전에 다음 클라이언트의 요청을 받는다는 의미이다.

기존 동기식 요청은 코드를 한줄 한줄 차례대로 실행한다. 그래서 하나의 작업에 걸리는 시간에 관계 없이 첫 번째 코드가 실행 된 뒤 다음 코드가 실행된다. 이렇게 되면 앞의 작업시간이 길수록 시간 및 자원의 낭비가 심해진다. 하나의 요청이 완료될 때 까지 기다리지 않고 동시에 다른 작업을 실행하는 비동기 호출로 극복할 수 있다.

따라서 한 시점에 여러 요청을 수행할 수 있게 되는데, 이는 자바스크립트가 싱글 스레드(Single-Thread) 로 동작하는 것과 관련이 있다.


자바스크립트가 실행될 때는 다음과 같은 요소들이 실행을 도와준다.

  • Call Stack: 자바스크립트에서 수행해야 할 함수들을 순차적으로 스택에 담아 처리
  • Web API: 웹 브라우저에서 제공하는 API로 AJAX나 Timeout등의 비동기 작업을 실행
  • Task Queue: Callback Queue라고도 하며 Web API에서 넘겨받은 Callback함수를 저장
  • Event Loop: Call Stack이 비어있다면 Task Queue의 작업을 Call Stack으로 옮김
setTimeout(() => console.log('hello world!'));
console.log('hello javascript!');

// hello javascript!
// hello world!

hello world! 가 출력되는 코드가 위에 있음에도 나중에 출력되는 것을 알 수 있다.

과정을 살펴보면,

  • 처음에 우선 setTimeout 함수가 실행되며 Call Stack에 setTimeout 함수가 추가된다.
  • setTimeout 함수는 자바스크립트 엔진이 처리하지 않고 Web API가 처리한다. (NodeJS의 경우 Timers 모듈) setTimeout함수는 Web API의 Timeout작업을 요청한 시간이 지나면 Task Queue로 인자로 받은 callback함수를 전달한다.
  • 그리고는 두 번째 라인에 작성한 console.log가 Call Stack에 추가된다. 그리고 Call Stack의 console.log가 실행되며 콘솔에는 'hello javascript!'라는 문자열이 출력된다.
  • 이 때, 자바스크립트의 Event Loop는 Call Stack이 비어있는지 항상 확인하는데 방금 console.log가 실행되며 Call Stack이 비워진 것을 확인한다.
  • Call Stack이 비워진 것을 확인한 Event Loop는 Task Queue에 있던 callback함수를 Call Stack으로 옮겨 작업을 수행한다. 콘솔에는 'hello world!'가 추가로 출력된 것을 볼 수 있다.
  • 모든 작업이 끝나게 되면 Call Stack과 Task Queue가 비워지게 된다.

JavaScript 런타임 환경

노드의 싱글 스레드는 C++로 짜여진 쓰레드 풀에 Heavy Load 한 일을 맡긴다. 싱글 스레드는 그저 이벤트를 처리해 주는 역할을 할 뿐이다. 앞선 클라이언트의 요청이 완료될 때 까지 기다리지 않고 다음 요청을 처리할 수 있는것은 Heavy Load 한 일을 뒷 단의 내부 C++ 쓰레드 풀이 감당하고 있었기 때문이다. 따라서 노드의 싱글 스레드는 여러 요청을 한 시점에 처리할 수 있게 되는 것이다.

JavaScript 런타임 환경의 정의는 다음과 같다.

JavaScript 로 짜여진 소스코드를 CPU가 이해할 수 있는 기계어(ex. 0과 1로 이루어진 bytecode)로 변환시키고 또한 프로그램의 메모리를 관리하는 시스템

이런 환경을 가능하게끔 하는 것이 바로 Chrome V8 엔진이다. Chrome V8 엔진은 우리가 알고 있는 구글의 크롬 웹브라우저에서 작동하는 엔진인데, 이 엔진이 브라우저 없이 작동할 수 있도록 만든 환경이 바로 노드이다.

위에서 언급했던 비동기 이벤트-기반의 처리를 이 Chrome V8 엔진이 담당한다. 즉, 싱글 스레드 기반의 동작 원리를 이해하고 JavaScript 로 코드를 작성하면 Heavy Load 한 일들을 Chrome V8 엔진이 처리해준다. 따라서, JavaScript 코드가 빠르고 안정성 있는 앱을 설계하는데 사용되는 것이다.


references

https://chanyeong.com/blog/post/44
https://medium.com/day34/node-js-%EB%85%B8%EB%93%9C%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%B4%EA%B3%A0-%EC%96%B4%EB%96%A0%ED%95%9C-%EA%B8%B0%EB%8A%A5%EB%93%A4%EC%9D%B4-%EC%9E%88%EB%8A%94%EA%B0%80-1-98e49e1100ab
https://zereight.tistory.com/855

좋은 웹페이지 즐겨찾기