1. 핵심 개념 이해하기
Node.js는 Chrome V8 Javascript 엔진으로빌드된 자바스크립트 런타임이다.
1.1 서버
노드를 통해 다양한 자바스크립트 애플리케이션을 실행할 수 있지만, 노드는 서버 애플리케이션을 실행하는데 제일 많이 사용한다.
서버란 네트워크를 통해 클라이언트에 정보나 서비스를 제공하는 컴퓨터 또는 프로그램을 말한다.
서버는 클라이언트의 요청에 대해 응답을 한다.
1.2 자바스크립트 런타임
런타임이란 특정 언어로 만든 프로그램들을 실행할 수 있는 환경을 뜻한다.
따라서 노드는 자바스크립트 프로그램을 컴퓨터에서 실행할 수 있다.
기존에는 자바스크립트 프로그램을 웹 브라우저 위에서만 실행할 수 있었다.
브라우저는 자바스크립트 런타임을 내장하고 있으므로 자바스크립트 코드를 실행 할 수 있다.
브라우저 외의 환경에서 자바스크립트를 실행하기 위한 여러 시도가 있었으나, 실행 속도 문제 때문에 호응을 얻지 못했다.
하지만 2008년 구글이 V8 엔진을 사용해 크롬을 출시하였고, V8 엔진은 다른 자바스크립트 엔진과 달리 매우 빨랐고, 2009년 V8 엔진 기반의 노드 프로젝트를 시작하였다.
노드는 V8과 더불어 libuv라는 라이브러리를 사용한다.
V8과 libuv는 C와 C++로 구현되어 있다.
1.3 이벤트 기반
이벤트 기반이란 에벤트가 발생할 때 미리 지정해둔 작업을 수행하는 방식을 의미한다.
특정 이벤트가 발생할 때 무엇을 할지 등록해둬야 하는 것을 이벤트 리스너에 콜백 함수를 등록한다고 표현한다.
이벤트 루프란 이벤트 발생 시 호출할 콜백 함수들을 관리하고, 호출된 콜백 함수의 실행 순서를 결정하는 역할을 담당한다. 노드가 종료될 때까지 이벤트 처리를 위한 작업을 반복하므로 루프라고 부른다.
function first() { // 첫번째 호출
second();
console.log("첫번째"); // 세번째 실행
}
function second() { // 두번째 호출
third();
console.log("두번째"); // 두번째 실행
}
function third() { // 세번째 호출
console.log("세번째") // 첫번째 실행
}
first();
/*
-- 콘솔 --
세번째
두번째
첫번째
*/
first 함수가 제일 먼저 호출되고, 그 안의 second 함수가 호출된 뒤, 마지막으로 third 함수가 호출된다.
그리고 호출된 순서와는 반대로 실행이 완료된다.
anonymous 함수는 처음 실행 시 전역 콘텍스트를 의미한다.
함수는 함수 호출이 끝나면 제일 위의 있는 순서대로 third, second, first anonymous 순으로 지워지고 호출 스택은 비어있게 된다.
function run() {
console.log("3초 후 실행");
}
console.log("시작");
setTimeout(run, 3000);
console.log("끝");
/*
-- 콘솔 --
시작
끝
3초 후 실행
*/
백그라운드란 setTimeout 같은 타이머나 이벤트 리스너들이 대기하는 곳이다. 여러 작업이 동시에 실행될 수 있다.
태스크 큐란 이벤트 발생 후, 백그라운드에서 태스크 큐로 타이머나 이벤트 리스너의 콜백 함수를 보낸다.
1. 전역 콘텍스트인 anonymous가 호출 스택에 들어간 뒤, setTimeout이 호출 스택에 들어간다.
2. setTimeout이 실행되면서 타이머와 함께 run 콜백을 백그라운드에 보내고 setTimeout은 호출된 스택에서 빠진다. 그 다음 anonymous가 호출 스택에서 빠진다.
3. 백그라운드에서는 3초를 센 후 run 함수를 태스크 큐로 보낸다.
4. 2번에서 anonymous까지 실행되어 호출 스택이 비어 있는 상태이다.
5. 이벤트 루프는 호출 스택이 비어 있으면 태스크 큐에서 하나씩 함수를 가져와 호출 스택에 넣고 실행한다.
6. 호출 스택으로 올려진 run이 실행되고 제거됨.
7. 이벤트 루프는 태스크 큐에 콜백 함수가 들어올 때까지 계속 대기한다.
1.4 논블로킹 I/O
이벤트 루프를 잘 활용하여 오래걸리는 작업을 효율적으로 처리할 수 있다.
작업에는 두가지 종류가 있다. 동시에 실행될 수 있는 작업과 동시에 실행될 수 없는 작업.
자바스크립트 코드는 동시에 실행될 수 없지만, I/O 작업 같은 것은 동시에 처리 가능하다.
I/O란 입력(Input)과 출력(Output)을 의미한다. 파일 시스템 접근, 네트워크를 통한 요청 같은 작업이다.
노드는 논블로킹 방식으로 처리하는 방법을 제공한다.
논블로킹이란 작업이 완료될 때까지 대기하지 않고 다음 작업을 수행하는 것을 의미한다.
블로킹이란 이전 작업이 끝나야만 다음 작업을 수행하는 것을 의미한다.
노드는 I/O 작업을 백그라운드로 넘겨 동시에 처리하기 때문에 동시에 처리될 수 있는 작업들을 최대한 묶어서 백그라운드로 넘겨야 시간을 절약할 수 있다.
1, 3, 5는 동시처리 가능하고 2, 4는 동시에 처리 불가능하다.
case 1의 경우 5초 정도의 작업이 걸리고 case 2의 경우 3초 정도로 단축된다.
이처럼 큰 성능 차이가 나기에 논블로킹 방식으로 코딩하는 습관을 들여야 한다.
function longRunningTask() {
// 오래 걸리는 작업
console.log("작업 끝");
}
console.log("시작");
longRunningTask();
console.log("다음 작업");
/*
-- 콘솔 --
시작
작업 끝
다음 작업
*/
위 예제는 블로킹 방식의 코드이다.
작업을 수행하는데 오래걸리는 longRunningTask함수가 있고 이 함수가 완료되기 전까지 "다음 작업"을 호출하지 않는다.
function longRunningTask() {
// 오래 걸리는 작업
console.log("작업 끝");
}
console.log("시작");
setTimeout(longRunningTask, 0);
console.log("다음 작업");
/*
-- 콘솔 --
시작
다음 작업
작업 끝
*/
위 예제는 setTimeout 함수를 이용한 논블로킹 방식이다.
setTimeout의 콜백 함수인 longRunningTask가 태스크 큐로 보내지므로 시작, 다음 작업, 작업 끝 순서로 실행된다.
I/O 작업이 없어도 오래 걸리는 작업을 처리해야하는 경우 논블로킹을 통해 실행 순서를 바꿔 대기하는 상황을 막을 수 있다.
논블로킹과 동시는 같은 의미가 아니다. 동시성은 동시 처리가 가능한 작업을 논블로킹 처리해야 얻을 수 있는 것이다.
1.5 싱글 스레드
싱글 스레드란 스레드가 하나뿐이라는 것을 의미한다.
이 말은 자바스크립트 코드가 동시에 실행될 수 없는 이유이기도 하다.
프로세스는 운영체제에서 할당하는 작업의 단위로 프로세스 간에는 메모리 등의 자원을 공유하지 않는다.
스레드는 프로세스 내에서 실행되는 흐름의 단위이다. 같은 주소의 메모리에 접근 가능하므로 데이터를 공유할 수 있다.
노드는 싱글 스레드이지만 엄밀히 말하면 싱글 스레드로 동작하지는 않는다.
노드를 실행하면 프로세스 하나가 생성된다. 그리고 그 프로세스에서 여러 스레드를 생성하는데, 그중에서 직업 제어할 수 있는 스레드는 하나 뿐이다. 그렇기 때문에 노드가 싱글 스레드라고 여겨지는 것이다.
멀티 스레딩 | 멀티 프로세싱 |
하나의 프로세스 안에서 여러 개의 스레드 사용 | 여러 개의 프로세스 사용 |
CPU 작업이 많이 사용될 때 사용 | I/O 요청이 많을 때 사용 |
프로그래밍이 어려움 | 비교적 쉬움 |
2. 서버로서의 노드
노드 서버의 장단점은 싱글 스레드, 논블로킹 모델이다.
노드는 개수는 많지만 작은 데이터를 실시간 주고 받는 네트워크, 데이터베이스, I/O에 특화되어 있다.
노드 12 버전에서 워커 스레드 기능의 안정화로 멀티 스레드 작업을 할 수 있게 되었다.
하지만 멀티 스레드 프로그래밍을 하는 것은 싱글 스레드에 비해 난이도가 높다.
또한, 멀티 스레드 프로그래밍을 하더라도 C, C++, Rust, Go와 같은 언어에 비해 속도가 느리다.
따라서 대규모 데이터 처리와 같이 CPU를 많이 사용하는 작업을 위한 서버로는 권장하지 않는다.
노드는 웹서버가 내장되어 있다.
노드외의 서버를 개발하면 Apache, nginx와 같은 웹서버나 Tomcat과 같은 웹 애플리케이션 서버를 추가로 설치하는 경우가 있다.
노드는 내장된 웹 서버를 사용하면 되지만, 서버 규모가 커짐에 따라 웹 서버를 노드 서버와 연결할 때도 있다.
노드는 자바스크립트를 언어로 사용한다.
웹 브라우저도 자바스크립트를 사용하기에 서버까지 노드를 사용하면 하나의 언어로 웹사이트를 개발할 수 있따.
노드는 JSON을 쉽게 처리 가능하다.
장점 | 단점 |
멀티 스레드 방식에 비해 적은 컴퓨터 자원 사용 | 기본적으로 싱글 스레드라서 CPU 코어를 하나만 사용 |
I/O 작업이 많은 서버로 적합 | CPU 작업이 많은 서버로는 부적합 |
멀티 스레드 방식보다 쉬움 | 하나뿐인 스레드가 멈추지 않도록 관리 필요 |
웹 서버가 내장되어 있음 | 서버 규모가 커졌을 때 서버를 관리하기 어려움 |
자바스크립트를 사용함 | 어중간한 성능 |
JSON 형식과 쉽게 호환됨 |
3. 서버로서의 노드
노드는 자바스크립트 런타임이므로 용도가 서버로만 국한되지 않는다.
사용 범위가 점점 늘어나서 웹, 모바일, 데스크톱 애플리케이션 개발에도 사용되기 시작했다.
대표적인 웹 프레임 워크로는 Angular, React, Vue 등이 있다.
'Programming > NodeJS' 카테고리의 다른 글
Node.js 교과서 [파일 시스템] #3.3 (0) | 2024.02.04 |
---|---|
Node.js 교과서 [노드 내장 모듈] #3.2 (0) | 2024.02.04 |
Node.js 교과서 [REPL, 모듈, 노드 내장 객체] #3 (1) | 2024.02.04 |
Node.js 교과서 [Front-end] #2.2 (0) | 2024.02.02 |
Node.js 교과서 [ES2015+] #2 (0) | 2024.02.02 |