Node.js는 Chrome V8 JavaScript 엔진으로 빌드된 자바스크립트 런타임입니다.
Node.js(이하 노드)의 공식 사이트 설명은 다음과 같습니다.
정의에 노드가 서버라는 말이 없는 이유는 노드가 서버만 실행할 수 있는 것이 아니기 때문입니다. 전반적으로 노드를 학습하는 사람들은 서버를 실행하는 방법을 공부하지만 서버 외의 자바스크립트 프로그램을 실행하는 런타임으로 사용되기도 합니다.
노드를 통해 다양한 자바스크립트를 애플리케이션을 실행할 수 있지만 노드는 서버 애플리케이션을 서버 애플리케이션을 실행하는데 제일 많이 사용합니다.
서버는 네트워크를 통해 클라이언트에 정보나 서비스를 제공하는 컴퓨터 또는 프로그램을 말합니다. 클라이언트란 요청을 보내는 주체로 브라우저일수도 있고, 데스크탑 프로그램일 수도, 다른 서버일 수도 있습니다.
웹이나 앱을 사용할 때는 우리의 데이터(아이디, 비밀번호, 이메일)와 서비스의 데이터가 생성됩니다. 이 데이터를 저장하는 곳이 바로 서버입니다.
노드는 자바스크립트 프로그램이 서버로서 가능하기 위한 도구를 제공하므로, 서버 역할을 수행할 수 있습니다.
노드는 자바스크립트 런타임입니다. 런타임은 특정 언어로 만든 프로그램들을 실행할 수 있는 환경을 뜻합니다. 따라서 노드는 자바스크립트 프로그램을 컴퓨터에서 실행할 수 있습니다.
기존에는 자바스크립트 프로그램을 웹 브라우저에서 위에서만 실행할 수 있었습니다. 브라우저는 자바스크립트 런타임을 내장하고 있으므로 자바스크립트 코드를 실행할 수 있습니다.

이벤트 기반이란 이벤트가 발생할 때 미리 지정해둔 작업을 수행하는 방식을 의미합니다. 이벤트로는 클릭이나 네트워크 요청 등이 있을 수 있습니다.
이벤트 기반 시스템에서는 특정 이벤트가 발생할 때 무엇을 할지 미리 등록해야합니다. 이를 이벤트 리스너에 콜백 함수를 등록한다고 표현합니다.
이벤트 기반 모델에서는 이벤트 루프(Event Loop) 개념이 등장합니다. 여러 이벤트가 동시에 발생했을 때 어떤 순서로 콜백 함수를 호출할지를 이벤트 루프가 판단합니다. 노드는 자바스크립트 코드의 맨 위부터 한 줄씩 실행합니다. 함수 호출 부분을 발견했다면 호출한 함수를 호출 스택에 넣습니다.
이벤트 루프에 대해 더 공부하고싶다면 자바스크립트의 이벤트루프를 읽어보세요.
이벤트 루프를 잘 활용하면 오래 걸리는 작업을 효율적으로 처리할 수 있습니다. 작업에는 두 가지 종류가 있는데, 동시에 실행될 수 있는 작업과 동시에 실행될 수 없는 작업입니다. 기본적으로 자바스크립트 코드는 동시에 실행될 수 없지만, 입출력 작업 같은 것은 동시에 처리될 수 있습니다.
논블로킹이란 이전 작업이 완료될 때까지 대기하지 않고 다음 작업을 수행하는 것을 의미합니다. 반대로 블로킹이란 이전 작업이 완료될 때 다음 작업으로 진행하는 것을 의미합니다.
노드에서는 실제로 이 방식을 거의 사용하지 않지만, 논블로킹은 setTimeout(콜백, 0) 메서드로 가장 간단하게 구현할 수 있습니다. 이 메서드를 호출하면 긴 콜백 메서드가 실행되기 전에 다른 작업을 먼저 처리합니다. 절대 동시에 동작하는 것은 아닙니다. 단순히 실행 순서만 바뀔 뿐입니다.
싱글 스레드란 스레드가 하나뿐이라는 것을 의미합니다. 싱글 스레드는 작성한 자바스크립트 코드가 동시에 실행될 수 없는 이유이기도 합니다. 스레드를 이해하기 위해선, 프로세스와 스레드의 차이를 알아야합니다.
노드가 싱글 스레드라는 말을 들어봤을겁니다. 하지만 엄밀히 말하면 싱글 스레드로 동작하지는 않습니다. 노드를 실행하면 먼저 프로세스가 하나 생성됩니다. 그리고 그 프로세스에서 스레드들을 생성하는데, 이때 내부적으로 스레드를 여러개 생성합니다. 이 중에서 우리가 다룰 수 있는 스레드는 단 1개입니다. 그래서 싱글스레드라는 말을 들어봤다고 생각합니다.
스레드 풀과 워커 스레드
노드가 싱글 스레드로 동작하지 않는 두 가지 경우가 있습니다. 하나는 스레드 풀이고, 다른 하나는 워커 스레드입니다.
노드는 기본적으로 싱글 스레드와 논블로킹 모델을 사용하므로 노드 서버 또한 동일한 모델일 수 밖에 없습니다. 따라서 노드 서버의 장단점은 싱글 스레드, 논블로킹 모델의 장단점과 크게 다르지 않습니다.
서버에는 기본적으로 입출력 요청이 많이 발생하므로, 입출력 처리를 잘하는 노드를 서버로 사용하면 좋습니다. 노드는 libuv 라이브러리를 사용해 입출력 작업을 논블로킹 방식으로 처리합니다. 따라서 스레드 하나가 많은 수의 입출력 작업을 감당할 수 있습니다.
노드 12 버전에서 워커 스레드 기능의 안정화로 멀티 스레드 작업을 프로그래밍 할 수 있게 되었지만, 이는 싱글스레드에 비해 난이도가 높습니다. 스레드가 작업을 나눠서 처리할 수 있게 직접 나눠주는 것이 상당히 어렵습니다. 또한 이는 C, C++, Go, Rust 언어에 비해 속도가 많이 느립니다.
따라서 굳이 멀티스레드 기능이 있다고 하더라도, 이미지나 비디오 처리, 대규모 데이터 처리와 같이 CPU를 많이 사용하는 작업을 위한 서버로는 권장하지 않습니다.
노드의 장점
노드의 단점