728x90
반응형

 

1장 노드 시작하기

1. 핵심 개념 이해하기

서버/ 자바스크립트 런타임/ 이벤트 기반/ 논블로킹 I/O/ 싱글 스레드
Node.js는 Chrome V8 Javascript 엔진으로 빌드된 자바스크립트 런타임
 

Node.js — Run JavaScript Everywhere

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org


서버

네트워크 ~> 클라이언트에 정보나 서비스를 제공하는 컴퓨터 또는 프로그램

클라이언트

  • 요청을 보내는 주체
  • ex. 브라우저, 데스크톱 프로그램, 모바일 앱, 다른 서버에 요청을 보내는 서버

 

웹 사이트 방문

  1. 주소창에 웹사이트 주소 입력(요청)
  2. 브라우저) 주소에 해당하는 컴퓨터 위치 파악
  3. 컴퓨터로부터 웹 사이트 페이지 받아와 요청자의 브라우저(클라이언트)에 띄움(응답)

자바스크립트 런타임

런타임: 특정 언어로 만든 프로그램들을 실행할 수 있는 환경

=> 노드: 자바스크립트 프로그램을 컴퓨터에서 실행할 수 있음 = 자바스크립트 프로그램 실행기

 

(기존) 브라우저: 자바스크립트 런타임 내장 

-> 자바스크립트 프로그램을 웹 브라우저 위에서만 실행할 수 있음
+ 브라우저 외 실행 환경에서 자바스크립트 실행 속도 문제

=> (해결) 2008년 구글 V8 엔진 사용해 크롬 출시

 

노드: V8 + libuv 라이브러리 사용 <- C와 C++로 구현

libuv 라이브러리: 이벤트 기반, 논블로킹 I/O 모델 구현

노드 외의 런타임: 번(https://bun.sh)/ 디노(https://deno.land)


이벤트 기반(event-driven)

  • 이벤트가 발생할 때 미리 지정해둔 작업을 수행하는 방식
    이벤트: 클릭이나 네트워크 요청 등
  • 특정 이벤트가 발생할 때 무엇을 할지 미리 등록해둬야 함
    = 이벤트 리스너(event-listener)에 콜백(callback) 함수를 등록
    • ex. 버튼을 클릭할 때 경고창을 띄우도록 설정하는 것
      • 클릭 이벤트 리스너에 경고창을 띄우는 콜백 함수를 등록
        -> 클릭 이벤트가 발생할 때마다 콜백 함수 실행돼 경고창 뜸
  • 이벤트 발생 -> 이벤트 리스너에 등록해둔 콜백 함수 호출
    / 발생한 이벤트 X or 이벤트 다 처리 -> 다음 이벤트가 발생할 때까지 대기

여러 이벤트가 동시 발생 -> 어떤 순서로 콜백 함수 호출할지 이벤트 루프(event loop)가 결정

  1. 자바스크립트 코드의 맨 위부터 한 줄씩 실행
  2. 함수 호출 부분 발견 -> 호출한 함수를 호출 스택(call stack)에 넣음

      
function first() {
second();
console.log('첫 번째');
}
function third() {
second();
console.log('첫 번째');
}
function third() {
console.log('첫 번째');
}
first();

anonymous 함수: 처음 실행 시의 전역 콘텍스트(global context)

콘텍스트: 함수가 호출되었을 때 생성되는 환경

자바스크립트 코드: 실행 시 기본적으로 전역 콘텍스트 안에서 돌아감


      
function run() {
console.log('3초 후 실행');
}
console.log('시작');
setTimeout(run, 3000);
console.log('끝');
  • 이벤트 루프
    • 이벤트 발생 시 호출할 콜백 함수 관리, 호출된 콜백 함수의 실행 순서 결정
    • 노드가 종료될 때까지 이벤트 처리를 위한 작업을 반복 => 루프(loop)
  • 백그라운드
    • setTimeout 같은 타이머나 이벤트 리스너들이 대기하는 곳
    • 자바스크립트가 아닌 다른 언어로 작성된 프로그램, 여러 작업이 동시에 실행될 수 있
  • 테스트 큐
    • 이벤트 발생 후, 백그라운드) 이벤트 리스너의 콜백 함수 -> 태스트 큐
    • = 콜백 큐: 정해진 순서대로 콜백들이 줄 서 있음
    • 콜백들은 보통 완료된 순서대로 줄을 서 있지만, 특정한 경우 순서가 바뀌기도 함 

  1. 호출 스택에 쌓임
    1. 전역 콘텍스트 anonymous가 호출 스택에 들어감
    2. setTimeout이 호출 스택에 들어감
  2. 호출 스택에 들어간 순서와 반대로 실행
    1. setTimout 실행 -> 타이머와 함께 run 콜백을 백그라운드에 보내고 setTimeout은 호출 스택에서 빠짐
    2. anoymous가 호출 스택에서 빠짐
  3. 백그라운드) 3초를 센 후(= 맡겨진 작업 완료) run 함수 -> 태스크 큐
  4. 이벤트 루프) 호출 스택 비어 있으면 태스트 큐에서 하나씩 함수 가져와 호출 스택에 넣고 실행
    • 이벤트 루프) 정해진 규칙 따라 콜백 함수들을 호출 스택으로 부름
    • 호출 스택) anonymous까지 실행 완료 -> 호출 스택 비어 있는 상황
  5. run 콜백을 태스크 큐에서 꺼내 호출 스택으로 올림 
  6. 호출 스택으로 올려진 run 실행, 실행 완료 후 호출 스택에서 제거
  7. 이벤트 루프) 태스트 큐에 콜백 함수가 들어올 때까지 계속 대기

IF. 호출 스택) 함수 ↑ -> 3초 지나도 run 함수 실행 X
=> 이벤트 루프) 호출 스택이 비어 있을 때만 태스트 큐에 있는 run 함수 호출
-> setTimeout의 시간이 정확하지 않을 수 있음


논블로킹 I/O 

  • 논블로킹(non-blocking)
    • 이전 작업이 완료될 때까지 대기하지 않고 다음 작업을 수행하는 것
    • 같은 작업을 더 ↓ 시간에 처리 (작업들이 모두 동시에 처리될 수 있는 작업 전제)
  • 블로킹(blocking): 이전 작업이 끝나야만 다음 작업을 수행하는 것


      
// 블로킹 방식
function longRunningTask() {
// 오래 걸리는 작업
console.log('작업 끝');
}
console.log('시작');
longRunningTask();
console.log('다음 작업');
// 시작 -> 작업 끝 -> 다음 작업
// setTimeout
console.log('시작');
setTimeout(longRunningTask, 0);
console.log('다음 작업');
// 시작 -> 다음 작업 -> 작업 끝

setTimeout(콜백, 0)

  • 코드를 논블로킹으로 만들기 위해 사용하는 기법 중 하나
  • setTimeout의 콜백 함수인 longRunnigTask -> 태스크 큐 => 순서대로 실행 X
    = 다음 작업이 먼저 실행된 후, 오래 걸리는 작업 완료
  • 밀리초 0으로 설정 -> 바로 실행 X => 기본적인 지연 시간 O (HTML5 브라우저: 4ms/ 노드: 1ms)

=> 오래 걸리는 작업 처리 -> 논블로킹 ~> 실행 순서 변경 -> 간단한 작업들이 대기하는 상황 막을 수 있음

 

논블로킹 != 동시

동시성: 동시 처리가 가능한 작업 -> 논블로킹 처리해야 얻을 수 있음


싱글 스레드

스레드 하나 -> 자바스크립트 코드 동시에 실행 X

  • 프로세스
    • 운영체제에서 할당하는 작업의 단위
    • 노드나 웹 브라우저 같은 프로그램은 개별적인 프로세스
    • 프로세스 간 메모리 등 자원 공유 X
  • 스레드
    • 프로세스 내에서 실행되는 흐름의 단위
    • 프로세스는 스레드 여러 개 생성해 여러 작업 동시에 처리 O
    • 부모 프로세스의 자원 공유
    • 같은 주소의 메모리에 접근 가능 -> 데이터 공유할 수 있음

노드 실행 -> 프로세스 생성 -> 내부적으로 스레드 여러 개 생성

But, 직접 제어할 수 있는 스레드는 1개 => 노드가 싱글 스레드라고 여겨짐

 

노드가 싱글 스레드로 동작하지 X 경우

  • 스레드 풀(Thread Pool)
    • 특정 동작을 수행할 때 스스로 멀티 스레드 사용
    • ex. 암호화, 파일 입출력, 압축 등 
  • 워커 스레드(Worker Threads)
    • 노드 12버전에서 안정화된 기능, 노드에서 멀티 스레드 사용할 수 있음
    • 직접 다수의 스레드 다룰 수 있고 CPU 작업(연산 ↑ 작업) 시 사용
Q: 여러 개의 일 동시에 처리할 수 있음 -> 멀티 스레드가 싱글 스레드보다 좋다? 
A: 꼭 그런 것은 아님

한 음식점에 점원 1명/ 손님 여러 명

  • 싱글 스레드(점원), 블로킹 모델
    • 점원 한 명이 주문 받아 주방에 넘기고, 주방에서 요리 나오면 손님에게 서빙 -> 다음 손님의 주문 받음
    • => 다음 손님은 이전 손님의 요리 나올 때까지 아무것도 하지 못하고 기다림 
    • (-) 비효율
  • 싱글 스레드, 논블로킹 모델
    • 점원이 한 손님 주문 받아 주방에 주문 내역 넘긴 뒤 다음 손님 주문 받음
    • 요리 끝나기까지 기다리는 대신, 주문이 들어왔다는 것만 주방에 계속 알려줌
    • 주방에서 요리 완료되면 완료된 순서대로 손님에게 서빙
    • => 요리의 특성(블로킹/논블로킹) -> 완료된 순서 다름 => 주문 들어온 순서 != 서빙하는 순서 
    • (+) 점원 한 명이지만 혼자 ↑ 일 처리 O
    • (-) 점원 한 명이 아파서 쓰러지면 큰 문제 
    • (-) 요리 하는데 걸리는 시간 ↑(CPU ↑ 쓰는 작업) -> 주문이 ↑ 들어왔을 때 버거울 수 있음

멀티 스레드

  • 손님 한 명 올 때마다 점원 한 명씩 붙어 주문 받고 서빙
  • (+) 점원 한 명에게 문제 생겨도 다른 점원으로 대체
  • (-) 손님 수 ↑ -> 점원 수 ↑/ 손님 수 ↓ -> 노는 점원 있음
    => 점원 새로 고용하거나 기존 직원 해고하는 데 비용 발생

=> 점원 여러 명(멀티 스레드) + 논블로킹 방식으로 주문 받으면 더 좋지만 프로그래밍 어려움

-> 멀티 프로세싱 방식 대신 사용

멀티 스레딩 멀티 프로세싱
하나의 프로세스 안에서 여러 개의 스레드 사용 여러 개의 프로세스 사용
CPU 작업 ↑ -> 사용 I/O 요청 ↑ -> 사용
프로그래밍 어려움 비교적 쉬움

2. 서버로서의 노드

싱글 스레드 + 논블로킹 모델 사용

  • (+) 서버) I/O 요청 ↑ 발생 -> I/O 처리를 잘하는 노드를 서버로 사용하면 좋음
    • libuv 라이브러리 사용: I/O 작업 논블로킹 방식을 처리 -> 스레드 하나가 ↑ 수의 I/O 혼자 감당 O
  • (+) 자바스크립트를 언어로 사용 -> 개발 생산성 ↑
  • (+) 웹 서버 내장 -> 입문자 쉽게 접근
    웹 서버: 아파치(Apahce), nginx, IIS/ 웹 애플리케이션 서버(WAS): 톰캣(Tomcat)

=> 개수 ↑ 크기 ↓ 데이터 실시간으로 주고받는 데 적합

-> 네트워크, 데이터베이스, 디스크 작업 같은 I/O에 특화

ex. 실시간 채팅 애플리케이션, 주식 차트, JSON 데이터를 제공하는 API 서버

  • (-) CPU 부하가 큰 작업에 적합 X
    • 작성한 코드 모두 스레드 하나에서 처리 => 코드가 CPU 연산 ↑ 요구 ->  감당하기 어려움
  • (-) 에러 제대로 처리 X -> 하나뿐인 스레드가 죽어 서버 전체 멈춤
  • (-) Go처럼 비동기에 강점을 보이는 언어 or nginx처럼 정적 파일 제공, 로드 밸런싱에 특화된 웹 서버에 비해 속도 ↓

멀티 스레드 프로그래밍 -> 난이도 ↑ + C, C++, Rust, Go에 비해 속도 ↓

=> CPU ↑ 사용하는 작업(이미지, 비디오 처리, 대규모 데이터 처리)에 적합 X

장점 단점
멀티 스레드 방식에 비해 ↓ 컴퓨터 자원 사용 기본적으로 싱글 스레드
-> CPU 코어를 하나만 사용
I/O 작업 ↑ 서버로 적합 CPU 작업 ↑ 서버로는 부적합
멀티 스레드 방식보다 쉬움 하나뿐인 스레드가 멈추지 않도록 관리 필요
웹 서버 내장 서버 규모 ↑ -> 서버 관리 어려움
자바스크립트 사용 어중간한 성능
JSON 형식과 쉽게 호환  

3. 서버 외의 노드

웹, 모바일, 데스크톱 애플리케이션 개발, 서버

  • 웹 프레임워크
    • 앵귤러(Angular) - 구글) 프런트엔드 앱
    • 리액트(React) - 페이스북
    • 뷰(Vue)
  • 모바일
    • 리액트 네이티브(React Native) - 페이스북, 인스타그램, 핀터레스트, 월마트, 테슬라 등
  • 데스크톱 애플리케이션
    • 일렉트론(Electron) - Atom, Slack, Discord, Visual Studio Code

출처

 

[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지 강의 | 제로초(조현영) - 인프런

제로초(조현영) | 노드가 무엇인지부터, 자바스크립트 최신 문법, 노드의 API, npm, 모듈 시스템, 데이터베이스, 테스팅 등을 배우고 5가지 실전 예제로 프로젝트를 만들어 나갑니다. 클라우드에 서

www.inflearn.com

728x90
반응형
김앩옹