Node.js 기본 개념 정리
Node.js를 공부하면서 필요한 핵심 개념을 정리
(공식문서 링크)
Node.js
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.
nodejs.org
Node.js란?
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.
(Chrome's V8 JavaScript 엔진 위에서 동작하는 JavaScript 런타임 환경)
즉, 브라우저 밖에서도 자바스크립트를 실행할 수 있게 해주는 플랫폼
Node는 내부적으로 V8과 libuv를 함께 사용
- V8: 오픈소스 자바스크립트 엔진
- libuv: 비동기 I/O를 위한 라이브러리 (이벤트 기반, 논블로킹 I/O 모델 구현)
이벤트 기반(Event-Driven)
Node.js는 이벤트 중심으로 동작
클릭, 네트워크 요청 등 이벤트 발생 시 등록된 콜백 함수가 실행되는 구조
이벤트 기반에 대한 예시 코드
function first() {
second();
console.log('first');
}
function second() {
third();
console.log('second');
}
function third() {
console.log('third');
}
first();
// 출력
third
second
first

자바스크립트는 호출 스택(Call Stack) 을 기반으로 위에서부터 아래로 실행
즉, third()가 먼저 실행되고, 이후 second(), first() 순서로 호출 스택이 비워짐.
- 호출 스택(Call Stack): 실행 중인 함수들이 쌓이는 스택
- 백그라운드(Background): setTimeout, 네트워크 요청 등 대기 중인 작업 영역
- 태스크 큐(Task Queue): 실행 대기 중인 콜백 함수들이 순서대로 줄 서 있는 큐
anonymous 함수는 처음 실행 시의 전역 컨텍스트를 의미.
아래는 특정 밀리초 이후에 코드를 실행하는 setTimeout 코드
function run() {
console.log('3초 후 실행');
}
console.log('시작');
setTimeout(run, 3000);
console.log('끝');
// 출력결과
시작
끝
3초 후 실행
이벤트 루프는 호출 스택이 비워졌을 때 태스크 큐에 있는 콜백을 스택으로 옮겨 실행
따라서 setTimeout이 3초 뒤에 완료되더라도, 호출 스택이 비어 있어야 콜백이 실제로 실행
즉, setTimeout의 지연 시간은 “정확한 실행 시간”을 보장하지 않음.
- 블로킹(Blocking): 이전 작업이 끝날 때까지 다음 작업이 대기
- 논블로킹(Non-Blocking): 이전 작업의 완료를 기다리지 않고 바로 다음 코드 실행
블로킹 예시
function longTask() {
console.log('작업 끝');
}
console.log('시작');
longTask();
console.log('다음 작업');
// 시작
// 작업 끝
// 다음 작업
논블로킹 예시
function longTask() {
console.log('작업 끝');
}
console.log('시작');
setTimeout(longTask, 0);
console.log('다음 작업');
// 시작
// 다음 작업
// 작업 끝
Node.js는 비동기 I/O 기반의 논블로킹 모델을 사용하기 때문에, I/O가 많은 서버 환경에서 효율적으로 동작.
전체적으로 한번 정리
- 이벤트 루프(Event Loop): 이벤트 발생 시 호출할 콜백 함수들을 관리하고, 호출된 콜백 함수의 실행 순서를 결정하는 역할을 담당.
- 노드가 종료될 때까지 이벤트 처리를 위한 작업을 반복하므로 루프라고 부림
- 백그라운드(Background): setTimeout 같은 타이머나 이벤트 리스너들이 대기하는 곳.
- 자바스크립트가 아닌 다른 언어로 작성된 프로그램이라고 봐도 무방하며, 여러 작업이 동시에 실행될 수 있음.
- 태스트 큐(Task Queue): 이벤트 발생 후 백그라운드에서는 태스크 큐로 타이머나 이벤트 리스너의 콜백 함수로 보냄.
- 정해진 순서대로 콜백들이 줄을 서 있으므로 콜백 큐라고도 불림.
- 콜백은 보통 안료된 순서대로 줄을 서 있지만, 특정한 경우 순서가 바뀌기도 함.
앞에 위치할수록 스택에 먼저 들어왔다고 생각할 수 있음.
예시)
호출스택: A - B - C인 경우에는 A가 먼저 들어오고 C가 제일 나중에 스택에 쌓임
만약 호출 스택에 함수가 너무 많이 들어 있다면 3초가 지난 후에서 run 함수가 실행되지 않을 수 있음.
이벤트 루프는 호출 스택이 비어 있을 때만 태스크 큐에 있는 run 함수를 호출 스택으로 가져오기 때문
이러한 이유로 setTimeout의 시간이 정확하지 않을 수도 있는 이유가 됨.
// 1. 이벤트 루프1
- 호출스택: anonymous - setTimeout()
- 백그라운드: 타이머 run 3초
- 태스크 큐: run
1-1) 호출스택에 쌓임
1-2) setTimeout 실행 시 콜백 run은 콜백 백그라운드로 보냄
1-3) 백그라운드에서 3초 후 태스크 큐로 보냄
// 2. 이벤트 루프2
- 호출스택:
- 백그라운드:
- 태스크 큐: run
2-1) 호출 스택 실행이 끝나 비워지면
2-2) 이벤트 루프가 태스크 큐의 콜백을 호출 스택으로 올림
// 3. 이벤트 루프3
- 호출스택: run()
- 백그라운드:
- 태스크 큐:
3-1) run이 호출 스택에서 실행되고 제거됨
3-2) 이벤트 루프는 태스크 큐에 콜백이 들어올 때까지 대기
노드의 싱글 스레드 구조
Node.js는 흔히 싱글 스레드라고 불리지만, 실제로는 내부적으로 여러 스레드를 사용
- 프로세스: 운영체제에서 실행되는 독립적인 프로그램 단위
- 프로세스 간 메모리 등 자원을 공유하지 않음.
- 스레드: 프로세스 내에서 실행되는 작업 흐름 단위
- 일반적으로 부모 자원을 온전히 공유하지 않음.
- vfork() 등 공유하게 만드는 기법도 존재하긴 함
Node.js는 하나의 메인 스레드로 자바스크립트 코드를 실행.
libuv의 스레드 풀을 통해 내부적으로 병렬 작업을 처리
즉, 노드는 엄밀히 말하면 싱글스레드로 동작하지는 않음.
- 1. 노드 실행시 프로세스가 하나 생성되고 그 프로세스에서 스레드들을 생성.
- 2. 이 때 내부적으로 스레드를 여러개 생성.
- 3. 다만, 우리가 직접 제어할 스레드는 하나뿐.(그래서 흔히 싱글스레드로 여겨짐.)
블로킹이 심하게 일어나는 작업이 아니라면 하나의 스레드로도 충분히 가능.
멀티스레드가 동작하는 경우
- 스레드 풀 (Thread Pool)
- 암호화, 파일 입출력, 압축 등 특정 작업을 내부적으로 병렬 처리
- 워커 스레드 (Worker Threads)
- Node.js 12 이상부터 도입된 기능
- CPU 연산이 많은 경우 직접 여러 스레드를 생성해 사용 가능
서버로서의 Node.js
Node.js는 실시간 통신과 I/O 중심의 작업에 강점을 보임.
- 실시간 채팅 서비스
- 주식/코인 실시간 차트
- JSON 기반의 API 서버
Node.js의 장점
- 적은 리소스로 높은 동시성 처리
- I/O 중심의 서버에 최적화
- 코드가 간결하고 유지보수 용이
- 웹 서버 내장 (추가 설정 불필요)
- JavaScript 사용으로 프론트엔드와 언어 통일
- JSON과의 높은 호환성
Node.js의 단점
- CPU 연산이 많은 경우 비효율적
- 싱글 스레드 특성상 한 작업이 전체를 블로킹할 수 있음
- 서버가 커질수록 관리 복잡도 증가
- 중간 수준의 성능 (CPU 연산과 I/O 모두 완벽하지 않음)
'backend > Node.js' 카테고리의 다른 글
| Node.js 익스프레스 웹 서버 만들기 (0) | 2023.07.23 |
|---|---|
| Node.js 패키지 매니저 (0) | 2023.07.23 |
| Node.js http 모듈로 서버 만들기 (0) | 2023.07.22 |
| Node.js 노드 기능 학습 정리 (0) | 2023.07.22 |
| Node.js 자바스크립트 알아둬야 할 부분 정리 (0) | 2023.07.17 |