D+3: Node.js

JJeong·2020년 12월 17일
0

[참고자료] 한눈에 끝내는 Node.js

자바스크립트 개념

클로저

외부 함수의 실행이 끝나고 외부 함수가 소멸된 이후에도 내부 함수가 외부 함수의 변수에 접근할 수 있는 구조.

<예제>

function f() {
    var a = [];
    var i;
    
    for (i = 0; i < 3; i++){
    	a[i] = function() {
        	return i;
        }
    }
  return a;
}

var b = f();

console.log( b[0]() );
console.log( b[1]() );
console.log( b[2]() );

다음을 실행하면 0, 1, 2가 출력되는 게 아니라 3, 3, 3이 출력된다. 함수를 통해 나온 값은 a이며 a[0], a[1], a[2]은 정해지지만 return 값 i가 정해지지는 않는다. return 값은 함수가 실행이 되었을 때만 도출되는 값이기 때문이다. 따라서 실행을 했을 때 i값을 찾아 상위 함수로 올라가게 된다. 이미 실행을 거친 상위 함수에서 현재 i값은 3이기에 위와 같은 결과가 나오게 된다.



Node.js

자바스크립트 엔진이란?

자바스크립트 코드를 실행하는 프로그램 혹은 인터프리터를 말한다. 주로 웹 브라우저를 위해 사용된다. 각각의 자바스크립트 엔진은 특정 버전의 ECMAScript를 구현하기 때문에 ECMAScript가 발전하는 만큼 엔진도 발전한다. 가장 대표적인 자바스크립트 엔진은 구글의 V8이다.

Node.js란?

Node.js는 서버사이드 자바스크립트이며 구글의 자바스크립트 엔진인 V8를 기반으로 구성된 일종의 소프트웨어 시스템이다. 이벤트 기반으로 개발이 가능하며 Non-Blocking I/O를 지원하기 때문에 비동기식 프로그래밍이 가능하다. 이 때문에 I/O 부하가 심한 대규모 서비스를 개발하기 적합하다고 할 수 있다.

이벤트 기반 비동기 방식

쓰레드 기반 vs 비동기 이벤트 기반

지금까지 대부분의 애플리케이션이 Blocking I/O를 사용했기에 멀티 태스킹을 위해 멀티 쓰레드를 사용할 수밖에 없었다. 하지만 이 방식은 네트워크에서 동시에 대규모 요청을 동시에 처리하는 데는 부적절하다.

Blocking I/O

하나의 프로세스가 어떤 자원을 사용하고자 할 때 그 자원을 다른 프로세스가 점유하고 있다면, 그 프로세스가 그 자원의 사용을 끝마칠 때까지 기다려야 하는 방식이다.

해당 그림에서 어플리케이션은 운영체제(커널)가 파일을 다 읽을 때까지 기다려야 하는데 이 상태를 Blocked되었다고 표현한다.

싱글 쓰레드와 멀티 쓰레드

멀티 쓰레드는 말 그대로 쓰레드 여러 개가 동시에 실행되어 요청을 처리한다는 개념이다. CPU의 시분할 개념으로 설명할 수 있다.

그림에서 위쪽처럼 처리할 때가 싱글 쓰레드, 아래처럼 처리할 때가 멀티 쓰레드 방식이다.

쓰레드 기반의 동작의 문제점

Blocking I/O 자체 문제점은 I/O 요청을 하고 응답이 올 때까지 아무것도 하지 않고 시간을 낭비한다는 점은 여전하다는 점이다. 또한 스케줄링을 위한 처리 시간과 문맥 전환(Context switch) 비용이 발생한다. 쓰레드를 분배하기 위해 사용되는 스케줄링 역시 CPU를 이용해야 한다. 쓰레드 간의 전환을 위해서 전환 직전의 쓰레드를 나중에 복귀시킬 때를 대비하여 그 상태를 저장해두어야 하는데, 이 역시 CPU를 이용한 연산이다.

이벤트 루프

이벤트 루프(Event Loop)라는 것은 작업을 요청하고 해당 작업이 완료되었을 때 어떤 작업을 진행할지에 대한 콜백함수를 지정하여 동작이 완료되었을 때 해당 콜백함수를 실행하게 되는 동작 방식을 말한다.

만약 클라이언트가 웹 서버에 HTTP 형식으로 요청하게 되면 서버에서는 이벤트 루프가 계속 돌고 있다가 이를 감지하고 알맞은 작업을 워커 쓰레드를 생성하여 실행한다. 이때 이벤트 루프는 해당 워커 쓰레드가 작업을 마친 뒤 그 결과와 함께 응답할 때까지 기다리는 것이 아니라 바로 루프로 복귀하여 다른 요청을 기다리게 된다.

0개의 댓글