[TIL][Node.js] 1. Node.js의 정의와 비동기처리방식(이벤트루프)

황연욱·2020년 9월 28일
1

Node.js

목록 보기
1/2

Node.js

참고자료

목차

Node.js란?

Node.js®는 Chrome V8 JavaScript 엔진으로 빌드된 JavaScript 런타임입니다.

  • 공식문서에서는 Node.js를 위와 같이 설명하고 있습니다.

  • Javascript(이하 JS)의 탄생목적은 웹(브라우저)에서 동적인 요소들을 처리하기 위함입니다.

  • 따라서 우리가 사용하는 모든 웹 브라우저(크롬, 사파리) 등은 각자 자바스크립트를 이해하고 실행할 수 있는 엔진을 가지고있어서 우리가 JS로 작성한 코드들이 웹브라우저에서 실행되어서 보여지는 것입니다.

  • JS의 생태계가 점점 커지고 활용성이 높아짐에 따라서 웹브라우저가 아닌 다른 환경에서도 JS로 짜여진 코드를 실행시키고자 하는 요구가 생겼고 이에 맞춰서 탄생하게 된 것이 Node.js입니다.

  • Node.js®는 Chrome V8 JavaScript 엔진으로 빌드된 JavaScript 런타임입니다.

    위의 구절을 다시 해석해보자면 Node.js는 JS를 해석하고 실행할 수 있는 여러개의 엔진 중에 chrome에서 사용하는 V8엔진을 통해서 Javascript를 웹이 아닌 다른 환경에서도 실행시켜줄 수 있는 환경입니다.

  • 이러한 Node를 이용해서 우리는 JS를 웹에서 뿐만 아니라 다른 환경에서도 실행시킬 수 있고, 이를 통해서 JS를 기반으로 작동하는 여러가지 Framework등을 사용할 수 있게 되었습니다.(React, ReactNative, Electron 등)

  • 또한 일반적인 PC에서도 JS를 사용할 수 있게 됨으로서 JS를 이용해서 요청과 응답을 처리할 수 있게 됨으로서 Server로서의 기능도 할 수 있게 되었습니다.

이벤트 루프

  • Node는 이벤트기반으로 동작합니다.

    이벤트 기반으로 동작한다는 것은 어떤 특정한 이벤트가 발생시 어떤 작업을 실행할 지 미리 지정해두는 것입니다.(프론트엔드 개발을 하신분들이라면. onClick, onChange등 여러 이벤트에 함수를 정의해놓는 방식에 익숙하실 겁니다.)

  • JS를 싱글스레드언어입니다. 이 말은 하나의 콜스택만을 가지고 있다는 뜻이며 위에 쌓인 스택이 실행되기 전까지는 그 아래의 스택들은 실행되지 못하고 대기하게 된다는 것입니다.

  • 그렇다면 만약 여러분이 이용하는 웹브라우저에서 극단적으로 생각해서 시간이 5분이 걸리는 네트워크요청이 제일 위의 스택에 쌓여있다고 생각해보면 그 네트워크 요청이 끝나기전까지는 웹브라우저를 render하지도 못하기에 브라우저는 멈춰있을것이며, 다른 작업을 실행할 수도 없을 것입니다.
    (이러한 상태를 Blocking이라고 표현합니다)

  • 버튼한번을 눌렀는데 5분동안 멈춰버리는 웹사이트를 이용할 사용자는 아무도 없습니다. 따라서 브라우저에서는 webAPI를 통해서 비동기처리를 지원하게 됩니다. 즉 시간이 오래걸릴 것 같은 동작들은 callStack에서 빠르게 빼버리고 JS callStack이 아닌, 다른 환경에서 동작을 하게하는 것입니다.
    (즉 시간이 오래걸리는 동작이 스택에서 자리를 차지하고 다른 동작들을 Block하지 못하게 다른 환경으로 옮겨서 동작시키는 것을 nonBlocking이라고 합니다)

  • 이러한 개념을 기반으로 이벤트루프가 동작합니다.

  • JS가 웹에서 비동기처리를 하는 방식은 싱글스레드인 JS Runtime에서 CallStack이 존재하며 이 CallStack에서 비동기 처리를 해야하는 동작들을 WebAPI로 보내고 이러한 webAPI에서는 해당하는 작업을 마친 후에 callBackQueue에 callback함수를 보낸 뒤 JS callStack이 비어진 경우 callbackQueue에서 callStack으로 순서대로 함수들이 실행되는 형태입니다.

  • 위의 과정을 EventLoop라고 합니다.

  • Node.js에서도 마찬가지로 비동기처리를 하지만, 노드환경에서는 webAPI가 없기때문에, libuv라는 C++기반의 라이브러리를 통해서 블로킹/논블로킹 처리를 하게됩니다. 즉 위의 webAPI부분이 libuv로 대치된 것이라고 생각하면 됩니다.

  • 또한 일반적으로 우리가 보통 CallBackQueue하면 생각하는 TaskQueue를 제외하고 하나의 큐가 더 존재하는데 이를 MicroTaskQueue라고 부릅니다.

  • 이 MicroTaskQueue에는 process.nextick에서 전달된 Callback함수와, resolve된 Promise들이 들어가게 되는데 이 MicroTaskQueue는 TaskQueue보다 선행되어서 실행됩니다.

  • 마이크로태스크큐가 태스크큐보다 선행되어서 실행되기에 마이크로태스크에서 재귀호출이 계속해서 일어나게되면 태스크큐에 들어가 있는 콜백함수들은 우선순위에 따라서 계속 실행이 안되고 있는 상황이 벌어질 수 있으니 이를 유의하면서 사용해야 합니다.

서버로서의 노드의 장단점

  • 일반적으로 Node를 공부해서 사용하고자 하는 사용자 대부분의 목적은 서버로서 노드를 동작시키는 것일겁니다.

  • 저 또한 서버단에서 일어나고 있는 일들에 대해서 궁금해지기 시작하고 프론트엔드 작업을 할 때 간단한 API들을 만들 수 있을 정도의 능력을 갖춰서 작업을 원할하게 해보고자 Node를 공부하기 시작했습니다.

  • 제가 Node를 선택한 이유는 JS를 기반으로 동작하기 때문에 새로운 언어를 배우는데에 비용을 투입하지 않아도 된다는 점이 매력적이고 더 생산적이라고 생각되어서 선택했습니다.

  • 하지만 Node를 공부하면서 어떤 환경에서 Node가 효율적이고, 어떤 환경에서는 최적의 효율을 낼 수 없는지에 대한 기본적인 인식정도는 있어야겠다는 생각을 해서 Node.js교과서라는 책에 적힌 내용과 구글링을 통해서 이를 한번 정리해보고자 합니다.
    (아래에 적힌 내용은 레퍼런스 삼은 내용들을 요약 정리한 것으로 스스로도 완전히 이해하지 못했지만 실제 사용해보고 개념을 점점 깨우쳐가면서 이해하고자 목표하고 있습니다.)

  • JS는 싱글스레드, 논블로킹 모델을 사용하기에 Input과 Ouput이 빈번하게 일어나는 환경에서 매우 효율적입니다.

  • 따라서 기본적으로 요청과 응답이 빈번하게 일어나는 서버단에서 활용하기에 적절합니다.

  • 하지만, 고도의 연산이 요구되는(CPU의 부하가 큰) 작업에서는 스레드 하나에서 처리하기 힘들기에 적합하지 않습니다.

  • 따라서 크기가 크지 않은 데이터들을 빈번하게 주고받는 형태의 서버에 적절합니다.(작은 데이터들의 실시간 통신이 필요한 경우)

  • 노드는 웹서버가 내장되어 있어서 별도의 웹서버를 설치하지 않아도 사용할 수 있어 편리합니다.(규모가 커질 경우에는 별도로 다른 웹서버를 연결해야 합니다.)

  • JSON파일로 많은 요청을 주고받는 현대 웹에서는 JSON은 자바스크립트 형식이기에 노드는 이를 쉽게 처리할 수 있습니다.

  • 노드의 안정성은 현재 많은 유명한 기업들(에어비앤비, 우버, 넷플릭스, 링크드인, 카카오, 위메프, 야놀자 등)과 심지어 NASA에서도 사용하고 있기에 검증되었다고 볼 수 있습니다.

마무리

  • 현재 Node.js를 틈틈히 공부해보고 있는데, 확실히 다른 언어를 새로 배워서 벡엔드단을 이해하는 것 보다 JS를 사용하기에 좀 더 친숙하게 접근할 수 있는 것 같습니다.

  • 개발공부는 T자형태로 해야한다는 말을 들었습니다. 전체적인 흐름을 이해하면서 자기가 특출나게 전문적인 분야가 있어야 한다는 뜻이라고 이해했습니다.

  • 저 또한 프론트엔드 개발을 함에 있어서, 단지 프론트단만 생각하면서 개발하는 것 보다 전체적인 웹개발의 시스템을 이해하고 개발하면 좀 더 효율적으로 설계할 수 있겠다는 목표를 가지고 차차 공부해나가보고자 합니다.

  • 제가 어떠한 아이디어가 있을 때 이를 프론트와 백엔드 단을 모두 생각하고 구성해서 프로토타입을 만들어 낼 수 있을 정도의 실력을 목표로 공부해나가야겠습니다.

profile
효율적이고 아름다운 코드를 쓰고싶은 호기심 많은 개발자입니다.

0개의 댓글