node js란 ?

1995년, 자바스크립트가 도입이 되면서 많은 브라우저들이 자바스크립트 엔진을 탑재하기 시작했다. 자바스크립트를 이해하고 실행할 수 있도록 브라우저가 개선되기 시작한 것이다.

사파리 브라우저의 ‘JavaScriptCore’, IE의 ‘Chakara’, Firefox의 ‘SpiderMonkey’, chrome의 ‘V8’ 가 있는데, 이 중, chrome의 V8 엔진은 JIT(Just-in-time-compilation)를 지원하는 획기적인 엔진이었다.

그 뒤에 Microsoft 에서는 IE를 대체할 Edge 를 내놓게 되는데, 처음에는 MS에서 가지고 있던 Chakara 엔진을 그대로 사용했으나 2021년에 크롬에서 사용하는 V8엔진을 사용하게 된다.

이렇게 자바스크립트가 흥행하면서 많은 개발자들이 자바스크립트를 배우고 사용하게 되는데, 2009년에 Ryan Dahl(라이언) 이라는 사람이 ‘열심히 배운 자바스크립트로 모든걸 다 할 수 있으면 ?’ 이라는 생각을 가지고 nodeJS를 처음 만들게 된다.

node.js 는 크롬의 막강한 V8 엔진을 이용하고 있고, 오픈 소스이며, 크로스 플랫폼 , 브라우저 밖에서도 사용할 수 있는 자바스크립트 런타임 환경이다.

브라우저 위에서의 자바스크립트는 동적인 웹사이트나 웹 어플리케이션을 만드는걸 도와주고, 노드 위에서의 자바스크립트는 노드가 설치된 어떠한 컴퓨터(윈도우,맥,리눅스)에서 backend & Server , Frond-end , scripting & Automation 등을 할 수 있게 도와준다.


왜 node를 배워야할까? 🤔

  • 자바스크립트로 모든걸 할 수 있다.
    • 자바스크립트로 클라이언트와 서버를 구현하게되면 두 가지 다른 프로그래밍 언어에 헷갈리거나 혼동이 오지 않기 때문에 생산성을 높일 수 있다. (넷플릭스사 같은 경우에도 자바로 백엔드 개발했었는데, 여러가지 문제에 봉착하면서 노드를 도입하게 되고, 도입한 이후 서버의 성능이 대폭 향상되었다)
    • 브라우저단은 자바스크립트, 서버는 자바 언어로 구현을 했다면 두가지 다른 프로그래밍 언어 때문에 추후 유지보수 및 변경이 힘들 수 있고, 생산성이 떨어질 수 있다.
  • 빠르게 서버와 클라이언트를 구성하여 프로토타이핑 할 수 있다.
  • 절반이 넘는 개발자들이 nodejs로 서버를 구성하고 있다.
    • 강한 개발 커뮤니티, 퀄리티 보장, 유용한 툴들을 많이 보유
  • 큰 기업들이 nodejs를 이용하여 서버나 서버사이드 렌더링을 구현하고 있다.
    • 링크드인, 넷플릭스, 우버, 나사, 이베이, 아마존, 페이팔, 레딧, 카카오톡, 쿠팡, 네이버 등
  • 쉽고 심플하지만, 강력하고 유연하다
    • 많은 기업들이 기존에 자바나 루비로 작성된 백엔드에 nodejs를 도입함으로써 더 높은 성능을 끌어냄
    • 개발자들의 생산성을 높일 수 있음
    • 서버의 개수가 많지 않아도, 더 좋은 성능을 기대해볼 수 있다.
  • 강력한 커뮤니티
    • npm이라는 노드 패키지 매니저를 이용하여 수 많은 라이브러리를 무료로 사용할 수 있고, 재사용 가능한 템플릿을 다운받아 사용할 수 있다.

nodejs의 특징 ✏️

1. JavaScript Runtime

Javascript Runtime 환경이다.

ECMAScript 표준과 WebAssembly를 구현한 크롬에서 사용하고 있는 강력한 자바스크립트 엔진인 ‘V8’은 C++로 작성이 되어있고, 오픈 소스 프로젝트이며, 성능이 좋다.

자바스크립트 런타임 환경이기 때문에 nodejs에서 자바스크립트 사용이 가능하다.

2. Single Thread

운영체제에서 여러가지 프로그램을 동시에 실행하게되면, 각 프로그램마다 프로세스 가 할당이 된다. 보기에 프로세스가 병렬적으로 실행되는 것 처럼 보이지만, 사실은 컴퓨터가 엄청나게 빠른 속도로 프로세스들에 시간을 할당하면서 마치 병렬적으로 실행되는 것 처럼 보이게 하는 것이다. (물론 어떤 cpu냐에 따라 정말 병렬적으로 실행될 수도 있다.)

(참고 : https://mingsayz.com/?p=1438)

예를 들어, 프로세스내에서 파일을 요청하고 받아와서, 음악을 재생한다고 해보자. 프로세스가 절차적으로만 진행을 하게 되면, 파일을 요청하고 받을때까지 기다렸다가 음악을 재생해야 한다. 또한, 이러한 일들을 처리하는 동안 사용자가 어플리케이션에서 클릭을 해도 클릭을 처리할 수 없다.

하지만 프로세스 내에서는 리소스를 공유하며 각기 다른 일을 하는 여러 개의 쓰레드가 존재 할 수 있다.

쓰레드(일꾼)들도 동시에 실행되는 것 같지만, 이것도 프로세스 내부에서 쓰레드들에 순차적으로 시간을 할당해서 동시에 실행되는 것처럼 보이게 하는 것이다.

그럼 쓰레드는 많을수록 좋은걸까? 🤔

쓰레드가 많으면 많을수록 좋을 것 같지만, 많다고 무조건 좋은 것은 아니다.

쓰레드가 동작하기 위해서 필요한 정보들을 개별적으로 만들어줘야하기 때문에 메모리 사용량이 증가하고, 프로세스 내의 공통된 자원을 공유하기때문에 리소스를 업데이트하는 동안 다른 스레드는 리소스를 사용할 수 없을 수도 있다.

이렇게 한 프로그램 내에서 여러개의 스레드를 쓰는걸 멀티스레딩이라고 하고, java같은 언어는 멀티스레딩을 할 수 있도록 cuncurrency API를 제공해준다.

자바와 반대로, 자바스크립트는 Single Thread 언어이다.

하나의 일을 수행하면, 그것이 끝날때까지 기다렸다가 다음 동작으로 넘어간다.

그냥 들어도 썩 좋지 않은데 어떻게 이런 자바스크립트로 nodejs에서 성능좋은 서버를 만들 수 있을까 ? 🤔 (클라이언트단의 경우, 웹 APIs와 event loop를 활용하는 것을 보았다)

바로 런타임 환경에서 제공하는 ‘Non-Blocking I/O’ , ‘Event-Driven’ 이 두가지 특징을 이용하여 여러가지 일들을 동시 다발적으로 진행할 수 있다.

3. Non-Blocking I/O

I/O란 input과 output을 의미하는데, 컴퓨터에서 파일을 읽고 쓰거나, 데이터베이스에 읽고 쓰거나, 네트워크에서 요청을 하고 응답을 받아오는 컴퓨터 내의 물리적인 것에 읽고 쓰는 것을 IO라고 말한다.

‘Blocking’ 이란, synchronous(동기적)인 것을 말한다. 하나를 요청하고 그것이 끝날때 까지 blocking을 했다가 다음으로 넘어가는 방식이다.

반대로, Non-Blocking 은 비동기적인 방식이라고 볼 수 있다. 하나의 태스크를 수행할 때 완료될때까지 기다리지 않고, 콜백을 던져주고 완료되면 콜백을 실행시켜달라고 요청한 후에 다음 태스크로 넘어간다. (브라우저 환경에서도 동일하게 동작 )

4. Event-Driven

Non-Blocking I/O와 밀접한 관련이 있다.

예를 들어, 파일을 다 읽으면 특정 콜백 함수를 호출하게끔 요청해두었다면, ‘파일이 다 읽어지는 이벤트’ 가 발생하면 등록한 콜백을 호출한다.

이렇게 이벤트를 통해서 등록한 콜백함수를 호출하는걸 Event-Driven이라 한다.