본문 바로가기

Programming/Node.js

1. Node.js 핵심 개념 이해 (3) - Non Blocking I/O

node js logo image

 

 

 

 

 

이번 아티클에서는 오래 걸리는 [작업]에 대한 효율적인 처리를 살펴보도록 하겠습니다. 기본적으로 자바스크립트를 통한 작업은 (1) 동시에 실행할 수 있는 작업과 (2) 동시에 실행할 수 없는 작업으로 구분됩니다. 

 

일단, 현재로서 우리가 작성하는 대부분의 코드는 동시에 실행할 수 없습니다. 하지만, 자바스크립트상에서의 실행이 아닌 I/O 작업은 동시에 처리가 가능합니다.

 

I/O(input, output)은 파일 시스템 접근(파일 읽기 쓰기 폴더 생성)이나 네트워크를 통한 요청 같은 작업을 의미합니다. 이러한 I/O 작업에 대해 노드는 논 블로킹(non-blocking) 작업 방식을 제공합니다. 이는 이전 작업의 완료를 기다리지 않고 다음 작업을 수행하는 작업 방식입니다. 이와 반대로 이전 작업의 종료 이후에 다음 작업이 가능한 방식을 블로킹(blocking) 방식으로 칭합니다. 

 

물론 이것은 자동으로 처리되는 것이 아니며, 논 블로킹 방식으로 처리를 하기 위해서는 특정 작업을 논 블로킹 방식으로 코딩해야 합니다. 

 

 

 


 

 

앞선 아티클에서 백그라운드, 태스크 큐에 대한 정의도 살펴보았습니다. 노드는 I/O 작업을 백그라운드로 넘겨서 동시에 처리하는 방식으로 작업을 진행합니다. 작업 5개 중 1,3,5번 작업이 동시에 작업이 가능한 논 블로킹 방식이라면, 약 60% 수준의 작업 시간으로 같은 업무를 처리할 수 있게 되죠. 예제 코드를 살펴보겠습니다. 

 

아래의 예제는 평범한 블로킹 방식의 코드입니다. 

 

function longRunningTask(){
    // 장시간 소요 작업
    console.log('FINISH');
}

console.log('START');
longRunningTask();

console.log('NEXT WORK');

/* 출력
START
FINISH
NEXT WORK
*/

 

 

특별할 것 없이, 코드 라인에 작성된 순서대로 START - FINISH - NEXT WORK가 출력됩니다. longRunningTask( )가 실행되고, 이 작업이 완료되어야 'NEXT WORK'가 출력되는 구조입니다. 

 

이번에는 이 코드를 논 블로킹 방식으로 구현해 보겠습니다. 여기서는 setTimeout( )을 사용합니다.

 

function longRunningTask(){
    // 장시간 소요 작업
    console.log('FINISH');
}

console.log('START');
setTimeout(longRunningTask, 0);

console.log('NEXT WORK');

/* 출력
START
NEXT WORK
FINISH
*/

 

우선 longRunnignTask를 setTimeout의 콜백 함수로 전달했습니다. 그리고 지연 시간은 0으로 지정했습니다. setTimeout(callback, 0)을 사용하는 것은 코드를 논 블로킹 방식으로 구현하는 기본적인 기법입니다. 물론 실제로는 setImmediate를 사용하는데, 이는 따로 살펴보겠습니다. 

 

longRunningTask가 콜백 함수로 사용되었기 때문에, 태스크 큐에서 실행 스택으로 옮겨지므로 

 

하지만 여기서 console.log와 longRunningTask는 모두 우리가 작성했습니다. 그러므로 '동시'에 실행은 되지 않고, 순서만 바뀌게 됩니다. 동시에 실행이 가능하기 위해서는 기본적으로 I/O 작업이어야 한다고 설명했었죠? 그럼, 동시에 실행되지 않는 이런 경우에 논 블로킹 방식이 의미가 있을까요? 결론만 말하면, 있습니다. 최소한 아주 간단한 작업은 긴 시간을 필요로 하는 작업보다 먼저 실행할 수 있기 때문이지요.

 

* 여기서 착각할 수 있는데, '논 블로킹'은 '동시' 실행성과 동일한 의미가 아닙니다. "동시 실행이 가능한 작업을 논 블로킹으로 처리해야 동시성을 갖는다."라고 이해하시기를 바랍니다. 

 

* 또하나, 동기 / 비동기 처리는 블로킹 / 논 블로킹과 유사하지만 같은 개념은 아닙니다. 이 역시 추후 따로 살펴볼 예정입니다. 동기와 블로킹, 비동기와 논 블로킹이 유사하다고 생각하면 됩니다.