Node.js
서버
- 네트워크를 통해 클라이언트에 정보나 서비스를 제공하는 컴퓨터 혹은 프로그램
- 앱이나 웹 사용 시 필요한 데이터(아이디, 비밀번호, 이메일 등), 서비스의 데이터 생성되는데 이러한 데이터를 저장하고 클라이언트로 받아오는 역할.
- 서버가 클라이언트가 될 수도 있음(요청을 보낼 수 있음)
서버는 클라이언트 요청에 응답을 한다.
클라이언트
- 요청을 보내는 주체
- 브라우저 / 데스크톱 프로그램 / 모바일 앱 / 다른서버에 요청을 보내는 서버
예시
- 웹사이트 방문 시,
- 요청 : 주소창에 웹 사이트 주소 입력
- 응답 : 서버로부터 웹 사이트 페이지 받아와서 요청자의 브라우저에 띄움
- 모바일 앱 설치 시,
- 요청 : 플레이 스토어, 앱스토어에서 원하는 앱 고른 후 설치버튼 누름
- 응답 : 앱 내려받기 됨
노드
- Chrome V8 Javascript엔진으로 빌드된 자바스크립트 런타임
- 자바스크립트 프로그램을 컴퓨터에서 실행할 수 있음
- V8, libuv 라이브러리 사용 : C, C++로 구현(자바스크립트 코드를 노드가 알아서 연결해줌)
- V8 : 오픈 소스 자바스크립트 엔진
- libuv : 논블로킹 I/O, 이벤트 기반
노드는 자바스크립트 실행기임.
런타임
- 특정 언어로 만든 프로그램들을 실행할 수 있는 환경
기존 자바스크립트 프로그램 실행환경
- 웹 브라우저 위에서만 실행 가능
- 브라우저 : 자바스크립트 런타임 내장하고 있음.
- 2008년 구글 크롬 출시
이벤트 기반(Event-driven)
- 이벤트 발생 시 미리 지정해둔 작업을 수행하는 방식
- 이벤트 : 클릭, 네트워크 요청 등
- 이벤트 기반 시스템에서 특정 이벤트 발생 시, 무슨 동작을 할지 미리 등록
이벤트 리스너에 콜백 함수를 등록한다.
예시
- 버튼 클릭 시 경고창 띄우도록 설정
- 클릭 이벤트 리스너에 경고창을 띄우는 콜백함수 등록
- 이벤트 발생
- 콜백 함수가 실행됨
노드의 경우
- 이벤트 발생 시 이벤트 리스너에 등록해둔 콜백 함수 호출
- 발생한 이벤트 없거나 발생했던 이벤트 처리 완료되면 다음 이벤트 발생할 때까지 대기
이벤트 루프(Event Loop)
- 여러 이벤트 동시에 발생 시 어떤 순서로 콜백 함수를 호출할지 판단
function first() {
second();
console.log('first');
}
function second() {
third();
console.log('second');
}
function third() {
console.log('third');
}
first();
- 함수 호출 스택(call stack) : anonymous, first(), second(), third() 순
- 함수 실행 : third(), second(), first(), anonymous 순으로 호출 스택의 역순
- 실행되는 동안 호출 스택에 머물다가 실행 완료되면 호출 스택에서 사라짐.
anonymous 함수
- 처음 실행 시의 전역 컨텍스트(global context)
- context : 함수 호출되었을 때 생성되는 환경
- 자바 스크립트 코드는 실행 시 기본적으로 전역 컨텍스트 안에서 돌아감
function run(){
console.log('3초 후 실행');
}
console.log('시작');
setTimeout(run, 3000);
console.log('끝');
콘솔 : 시작, 끝, 3초 후 실행
- 호출 스택에 setTimeout() 쌓임(타이머 실행 전)
- setTimeout() 실행 시 콜백 run은 백그라운드로 보내짐(setTimeout은 호출스택에서 pop), anonymous 실행 후 pop
2.1. 호출 스택이 비어 있으면 이벤트 루프는 태스크 큐에서 함수를 하나씩 가져와서 호출 스택에 넣고 실행함.
- 백그라운드에서 3초 후 태스크 큐로 보냄
- 호출 스택 실행이 끝나 비워짐
- 이벤트 루프가 태스크 큐의 콜백을 호출 스택으로 올림
- run 실행되고 pop
- 이벤트 루프는 태스크 큐에 콜백이 올때까지 대기.
이벤트 루프
- 이벤트 발생 시
호출할 콜백 함수들 관리
- 호출된 콜백 함수의 실행 순서 결정하는 역할
- 노드 종료될 때까지 이벤트 처리를 위한 작업을 반복하므로 루프라고 부름
백그라운드
- 타이머(setTimeout), 이벤트 리스너들이 대기하는 곳
- 자바스크립트가 아닌 다른 언어로 작성된 프로그램
- 여러 작업이 동시에 실행될 수 있음
태스크 큐
- 정해진 순서대로 콜백들이 줄 서 있으므로 콜백 큐라고 부름
- 이벤트 발생 후 태스크 큐로 이벤트 리스너, 타이머의 콜백함수가 올라옴
- 특정한 경우에는 순서가 바뀌기도 함
- 여러 개의 큐로 이뤄져 있음.
싱글스레드
- 자바스크립트 코드는 싱글 스레드이기 때문에 코드가 동시에 실행 X
노드 실행 시 프로세스 하나 생성되고 그 프로세스 내 여러개의 스레드를 생성하지만, 직접 제어가능한 스레드는 하나뿐 === 싱글스레드처럼 여겨짐
- 블로킹이 심하게 일어나는 작업만 아니면 괜찮음. 논블로킹으로 대기 시간을 최대한 줄이는 방법도 있음.
프로세스
- 운영체제에서 할당하는 작업의 단위
- 노드나 웹 브라우저 같은 프로그램들
- 프로세스 간 메모리 등의 자원 공유 X
스레드
- 프로세스 내 실행되는 흐름의 단위
- 스레드를 여러 개 생성해 여러 작업을 동시에 처리할 수 있음
- 부모 프로세스의 자원 공유
- 같은 주소의 메모리에 접근 가능하므로 데이터 공유 가능
멀티스레드 vs 싱글스레드
예시
- 싱글스레드, 블로킹
- 1명의 점원, 여러 명의 손님
- 주문을 받은 후 요리 나올때까지 대기하다가 서빙 후 다음 주문 받음(블로킹)
- 제일 비효율적임
- 싱글스레드, 논블로킹
- 노드 채택 방식
- 여러 명의 손님 주문을 다 받음
- 요리 완료된 순대로 서빙
- 블로킹, 논블로킹 방식에 따라 요리 완료 순서는 다르므로 주문순서와 서빙순서는 미일치
- 점원이 쓰러지거나 요리 시간이 오래걸리는 요리가 많이 들어오면(CPU 많이 쓰는 작업) 버거움
- 멀티스레드, 블로킹
- 손님 한 명 당 점원 1명씩 배치
- 점원 한 명 없어도 다른 인원으로 배치 가능
- 손님이 늘어나면 점원도 같이 늘어나고, 손님이 줄어들면 노는 점원 발생
- 점원 고용, 해고에 따라 비용 발생 및 구현도 어려움..
멀티스레딩 vs 멀티프로세싱
- 멀티스레딩
1.1. 하나의 프로세스 안에서 여러 개의 스레드 사용
1.2. CPU 작업이 많을 때 사용
1.3. 프로그래밍 어려움
- 멀티프로세싱
2.1. 여러 개의 프로세스 사용
2.2. I/O 요청이 많을 때 사용
2.3. 프로그래밍이 비교적 쉬움
스레드풀
- 노드가 특정 동작을 수행할 때 스스로 멀티스레드 사용
- 암호화, 파일 입출력, 압축 등
워커 스레드
- 노드 12버전 이후부터는 멀티 스레드 가능해짐
- CPU 작업이 많은 경우 워커 스레드 이용하면 됨.
논 블로킹 I/O
- 코드는 동시에 실행될 수 없으나 자바스크립트 아닌 I/O 작업 같은 것은 동시에 처리 가능
- 파일 시스템 접근(파일 읽기, 쓰기, 폴더 만들기 등), 네트워크를 통한 요청 등
- 이전 작업이 완료될 때까지 대기하지 않고 다음 작업을 수행함
블로킹
동시에 처리할 수 있는 작업들은 최대한 묶어서 백그라운드로 넘겨 시간 절약
예시
- w1,2,3,4,5 중 1,3,5는 동시에 처리 가능함.
- 블로킹 방식에서는 모든 작업 처리 시 5초 소요
- 논블로킹 방식에서는 모든 작업 처리 시 3초 소요
작업 순서에 따라 성능이 크게 달라짐.
function longRunTask(){
...//블로킹 방식의 I/O 작업 수행(시간 오래 걸리는 작업)
console.log('작업 끝');
}
console.log('시작');
longRunTask();
console.log('다음');
시작, 작업 끝, 다음
function longRunTask(){
...//블로킹 방식의 I/O 작업 수행(시간 오래 걸리는 작업)
console.log('작업 끝');
}
console.log('시작');
setTimeout(longRunTask, 0);
console.log('다음');
시작, 다음, 작업 끝
- setTimeout(콜백, 0) : 코드를 논블로킹으로 만들기 위한 코드(0초라도 기본 지연시간 있어서 바로 실행되지는 않음)
- 논블로킹 방식은 단지 실행순서를 바꿔주는 것임.
- 실행 순서를 바꿔 간단한 작업들이 대기하는 상황을 막음
논블로킹 != 동시(concurrent)
- 동시성 : 동시 처리 가능한 작업을 논블로킹 처리해야 함