Node.js®는 Chrome V8 JavaScript 엔진으로 빌드된 JavaScript 런타임입니다.
Node.js의 홈페이지에 들어가면 메인페이지에 나오는 문장이다.
Javascript 언어는 HTML
웹페이지에 여러가지 기능을 넣기 위해 만들어진 언어이다.
우리가 짠 Javascript 코드는 웹브라우저가 실행을 해주는데, Chrome 브라우저 안에도 Javascript 실행 엔진이 있다.
(브라우저의 종류에 따라 사용하는 엔진이 다르다.)
이것을 Google이 V8이라고 이름을 지었는데 V8의 성능을 매우 좋게 만들어서 후에 독립적인 실행파일로 출시를 했는데 이것을 Node.js라고 부른다.
그래서 Node.js는 Javascript의 파일 실행기일 뿐이다.
Node.js를 설치하면 컴퓨터 어디에서나 Javascript로 작성한 파일을 실행할 수 있다.
(Node.js를 Javascript 런타임이라고 부른다.)
그래서 Node.js만 쓰면 코드 에디터, 윈도우 프로그램 등의 프로그램을 만들 수 있다 보니Node.js로도 웹서버를 만들기 시작했다.
현재도 Node.js 특유의 간결한 문법과 성능 덕분에 아직 인기가 많다.
그리고 웹개발을 할 때 프론트엔드에서 Javascript를 꼭 사용해서 개발을 하기 때문에 프론트엔드 개발자들이 Node.js로 백엔드 서버 개발도 쉽게 접근할 수 있다는 것도 장점이다.
Node.js는 싱글 스레드 non-blocking I/O 기반 비동기 방식으로 작동한다.
여기서 싱글 스레드란 한 프로세스에서 한가지 작업을 실행하기 위해 순차적으로 실행되는 하나의 흐름이다.
(동시에 하나의 코드만 실행할 수 있다는 뜻)
여기서 헷갈릴 수 있는 점은,
Javascript는 싱글 스레드로 하나의 힙 영역과 하나의 콜 스택을 가지는데 하나의 콜 스택을 가지기 때문에 한번에 하나의 일 밖에 하지 못한다.
그래서 앞의 수행이 완료될 때 까지 다음 수행을 하지 못하고 기다리는 동기적 처리를 한다.
하지만, Javascript가 싱글 스레드라는 말을 정확히 하면 Javascript 자체(Javascript 엔진이 단일 호출 스택을 사용)의 관점에서만 맞는 얘기이고, 실제 Javascript가 구동되는 환경(Javascript 런타임 / 브라우저 or Node.js)에서는 주로 멀티 스레드를 사용한다.
결론적으로, Javascript 자체는 싱글 스레드이지만, Javascript 런타임은 싱글 스레드가 아니다.
그리고 non-blocking I/O란 입출력 작업을 진행할 때, 작업의 완료를 기다리지 않고 다른 작업을 계속 수행할 수 있도록 하는 입출력 처리 방식이다.
즉, I/O 작업이 blocking 되지 않고 해당 작업이 완료되길 기다리는 동안 다른 작업을 병렬적으로 실행할 수 있다.
예를 들어, 파일을 읽거나 네트워크 요청을 처리하는 경우에 일반적인 blocking I/O 방식은 해당 작업이 끝날때까지 프로그램이 대기 상태가 된다.
반면, non-blocking I/O 방식을 사용하면 이러한 작업이 백그라운드에서 처리되고 프로그램은 다른 작업을 계속 진행한다.
작업이 완료되면 콜백 함수나 이벤트를 통해 결과를 반환 받는다.
Node.js에선 이런 non-blocking I/O방식이 기본으로 적용되어 있어서 많은 사용자의 동시 접속을 효율적으로 처리할 수 있다.
내부적으로는 libuv 라이브러리를 사용해 멀티 스레드를 활용해 비동기 작업을 처리한다.
위와 같은 결과로 Node.js는 싱글 스레드 모델을 유지하면서도 뛰어난 성능과 확장성을 제공한다.
개발자가 클라이언트와 서버 모두 Javascript를 이용해 개발할 수 있어서 언어를 전환할 필요가 없다.
이렇게 되면 생산성이 높아지고 빠르고 프로토 타입을 만들거나 배포가 가능해 개발 효율성이 좋아진다.
그리고 서버와 클라이언트 간에 공통적으로 사용되는 로직이나 유틸리티 함수 등을 Javascript 언어로 쉽게 공유할 수 있어 코드 재사용성이 좋다.
이로 인해 코드의 중복을 최소화하고 유지보수를 더 쉽게 할 수 있다.