#1 핵심개념 이해하기
✅ 공식사이트에 정의된 Node.js
Node.js는 Chrome V8 Javascript 엔진으로 빌드된 자바스크립트 런타임
노드는 V8과 더불어 libuv를 사용함.
- V8: 오픈소스 자바스크립트 엔진
- libuv: 비동기 I/O
- 노드의 특성인 이벤트 기반, 논블로킹 I/O 모델을 구현하고 있음.
✅ 이벤트 기반
- 노드의 이벤트로는 클릭이나 네트워크 요청 등이 존재
이벤트 리스너에 콜백 함수를 등록한다고 표현.
아래 함수를 실행시켰을 때의 결과는?
function first() {
second()
console.log('first')
}
function second() {
third();
console.log('second')
}
function third() {
console.log('third')
}
first();
// 출력
third
second
first
anonymous 함수는 처음 실행 시의 전역 컨텍스트를 의미.
아래는 특정 밀리초 이후에 코드를 실행하는 setTimeout 코드
function run() {
console.log('3초 후 실행');
}
console.log('시작');
setTimeout(run, 3000);
console.log('끝');
// 출력결과
시작
끝
3초 후 실행
왜 이렇게 실행되는걸까?
- 이벤트 루프: 이벤트 발생 시 호출할 콜백 함수들을 관리하고, 호출된 콜백 함수의 실행 순서를 결정하는 역할을 담당. 노드가 종료될 때까지 이벤트 처리를 위한 작업을 반복하므로 루프라고 부른다.
- 백그라운드: setTimeout 같은 타이머나 이벤트 리스너들이 대기하는 곳. 자바스크립트가 아닌 다른 언어로 작성된 프로그램이라고 봐도 무방하며, 여러 작업이 동시에 실행될 수 있음.
- 태스트 큐: 이벤트 발생 후 백그라운드에서는 태스크 큐로 타이머나 이벤트 리스너의 콜백 함수로 보냄. 정해진 순서대로 콜백들이 줄을 서 있으므로 콜백 큐라고도 불림. 콜백은 보통 안료된 순서대로 줄을 서 있지만, 특정한 경우 순서가 바뀌기도 함.
실행순서 정리를 위한 용어 정리
- 호출스택(이벤트 루프)
- 백그라운드
- 태스크 큐
앞에 있을수록 스택에 먼저 들어왔다고 정의
예를들어) 호출스택: A - B - C인 경우에는 A가 먼저 들어오고 C가 제일 나중에 스택에 쌓임
✅ 실행순서 정리
// 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) 이벤트 루프는 태스크 큐에 콜백이 들어올 때까지 대기
만약 호출 스택에 함수가 너무 많이 들어 있다면 3초가 지난 후에서 run 함수가 실행되지 않을 수 있다. 이벤트 루프는 호출 스택이 비어 있을 때만 태스크 큐에 있는 run 함수를 호출 스택으로 가져오기 때문에. 이것이 setTimeout의 시간이 정확하지 않을 수도 있는 이유.
✅ 논블로킹 I/O
- 논블로킹: 이전 작업이 완료될 때까지 대기하지 않다가 수행
- 블로킹: 이전작업이 끝나야만 다음 작업을 수행
// ✅ 블로킹 방식의 코드
function longRunningTask() {
// 오래 걸리는 작업
console.log('작업 끝');
}
console.log('시작');
longRunningTask();
console.log('다음 작업');
// 출력순서
시작
작업 끝
다음 작업
// ✅ 논블로킹 방식의 코드
function longRunningTask() {
// 오래 걸리는 작업
console.log('작업 끝');
}
console.log('시작');
setTimeout(longRunningTask, 0);
console.log('다음 작업');
// 출력순서
시작
다음 작업
작업 끝
✅ 노드에서의 싱글스레드
프로세스: 운영체제에서 할당하는 작업의 단위. 노드나 웹 브라우저 같은 프로그램은 개별적인 프로세스. 프로세스 간 메모리 등 자원공유 X
스레드: 프로세스 내에세 실행되는 흐름 단위. 프로세스는 스레드를 여러개 생성해 여러 작업을 동시에 처리. 스레드는 부모 자원을 공유.
노드는 엄밀히 말하면 싱글스레드로 동작하지는 않음. 노드 실행시 프로세스가 하나 생성되고 그 프로세스에서 스레드들을 생성하는데, 이 떄 내부적으로 스레드를 여러개 생성. 다만, 우리가 직접 제어할 스레드는 하나 뿐. 그래서 흔히 싱글스레드로 여겨짐.
블로킹이 심하게 일어나는 작업이 아니라면 하나의 스레드로도 충분히 가능.
노드가 싱글스레드로 동작하지 않는 두가지 경우가 존재.
1. 스레드 풀(thread pool)
- 스레드 풀은 노드가 특정 독작을 수행할 때 스스로 멀티 스레드 사용. (ex. 암호화, 파일 입출력, 압축)
2. 워커 스레드(worker threads)
- 노드 12에서 안정화 된 기능으로, 멀티 스레드를 사용할 ㅅ ㅜ있음. 직접 다수의 스레드를 다룰 수 있고 CPU작업이 많은 경우 워커 스레드를 사용
✅ 서버로의 노드
싱글스레드의 특성상 개수는 많지만, 크기는 작은 데이터를 실시간으로 주고 받는 데 적합.
ex) 실시간 채팅 앱, 주식 차트, json 데이터를 제공하는 api 서버가 노드를 많이 사용
노드의 장점
1. 멀티 스레드 방식에 비해 적은 컴퓨터 자원 사용
2. I/O 작업이 많은 서버로 적합
3. 멀티 스레드 방식보다 쉬움
4. 웹 서버가 내장되어 있음
5. 자바스크립트를 사용함
6. JSON 형식과 쉽게 호환이 됨
노드의 단점
1. 기본적으로 싱글 스레드라서 CPU 코어를 하나만 사용
2. CPU 작업이 많은 서버로는 부적합
3. 하나뿐인 스레드가 멈추지 않도록 관리 필요
4. 서버 규모가 커졌을 떄 서버를 관리하기가 어려움
5. 어중간한 성능
'Node.js' 카테고리의 다른 글
[Node.js] #6 익스프레스 웹 서버 만들기 (0) | 2023.07.23 |
---|---|
[Node.js] #5 패키지 매니저 (0) | 2023.07.23 |
[Node.js] #4 http 모듈로 서버 만들기 (0) | 2023.07.22 |
[Node.js] #3 노드 기능 알아보기 (0) | 2023.07.22 |
[Node.js] #2 알아둬야 할 자바스크립트 (0) | 2023.07.17 |