노드란?
Chrome V8 Javascript 엔진으로 빌드된 Javascript 런타임
노드는 서버 실행 뿐만 아니라 런타임으로서도 사용한다.
서버
노드를 통해 다양한 자바스크립트 애플리케이션을 실행할 수 있지만, 서버 애플리케이션을 실행할 때 제일 많이 사용합니다.
서버
네트워크를 통해 클라이언트에 정보나 서비스를 제공하는 컴퓨터 또는 프로그램입니다.
클라이언트
요청을 보내주는 주체로 브라우저, 데스크톱 프로그램, 모바일 앱 혹은 다른 서버일 수 있습니다.
웹이나 앱을 사용할 때 데이터(아이디, 비밀번호, 이메일 등)를 저장하고 클라이언트로 받아오는 것이 서버입니다.
예를 들어 아이디와 비밀번호를 클라이언트에서 입력했을 때 서버에 있는지 요청하고 서버에서 확인하여 응답하는 것이라고 볼 수 있습니다.
서버는 요청을 보내는 것 뿐만 아니라 요청을 보내는 클라이언트 역할 또한 수행할 수 있습니다.
응답 시에 항상 Yes가 아닌 No라고 응답할 수 있습니다.
자바스크립트 런타임
노드는 자바스크립트 런타임입니다.
런타임
특정 언어로 만든 프로그램들을 실행할 수 있는 환경입니다.
컴퓨터 언어 안에 쓰인 프로그램을 관리하기 위해 특정한 컴파일러나 가상 머신이 사용하는 기본 코드의 라이브러리나 프로그램을 가리키는 런타임 라이브러리라고도 합니다. (출처 위키백과)
노드는 V8과 더불어 libuv라는 라이브러리를 사용합니다. (V8은 크롬에 사용되는 엔진입니다.)
libuv 라이브러리는 노드의 특성인 이벤트 기반, 논 블로킹 I/O 모델을 구현하고 있습니다.
*블로킹(Blocking) I/O 및 동기(Synchronous) I/O : I/O 작업 시에 대상 파일의 디스크립터(Descriptor)가 준비되어 있지 않은 프로세스는 시스템 호출 응답 대기상태가 되어 프로그램 처리를 진행할 수 없다.
*논-블로킹(non-blocking) I/O: 호출 직후 프로그램으로부터 제어가 돌아와 다음 처리로 바로 진행할 수 있다. 프로세스가 블로킹 상태가 아니어서 CPU를 다른 프로세스에서 사용함으로써 I/O 대기시간을 줄일 수 있다.
*비동기(Asynchronous) I/O : 함수 호출 이후 완료 전에 반환하여 다름 함수가 호출될 수 있게합니다. 회신은 시그널 또는 콜백의 형태로 이루어집니다.
이들의 자세한 특징과 종류는 다른 포스팅에서 알아봅시다. 파면 팔수록 계속 나오네요 ㅎㅎ;;
이벤트 기반
이벤트 기반 (event-driven)
이벤트가 발생할 때 미리 지정해둔 작업을 수행하는 방식을 의미합니다. (클릭, 네트워크 요청 등) 그렇기 때문에 이벤트 기반 시스템에서는 특정 이벤트가 발생할 때 무엇을 할지 미리 등록해야 합니다. 이러한 행위를 이벤트 리스너(event listener)에 콜백(callback) 함수를 등록한다고 표현합니다.
예를 들어, 경고창을 띄우는 콜백 함수를 등록해 놓으면 버튼을 누를 때 콜백 함수가 실행되어 경고창이 뜹니다.
노드 또한 이벤트 기반 형식으로 동작하기 때문에 이벤트 발생시 리스너에 등록된 콜백 함수를 호출합니다. 모든 이벤트를 처리하면 노드는 다음 이벤트 발생까지 대기합니다.
이벤트 루프 (event loop)
이벤트 발생 시 호출할 콜백 함수들을 관리하고, 호출된 콜백 함수의 실행 순서를 결정하는 역할을 담당합니다. 노드가 종료될 때까지 이벤트 처리를 위한 작업을 반복합니다.
여러 이벤트가 발생했을 때 어떤 순서로 콜백 함수를 호출할지 이벤트 루프가 판단합니다.
function first(){
second();
console.log('첫 번째');
}
function second(){
third();
console.log('두 번째');
}
function third(){
console.log('세 번째');
}
first();
다음과 같이 콘솔에 입력했을 때 (콘솔 입력 환경)
이러한 결과가 나옵니다.
콘솔에서 호출 스택을 확인하려 했으나 찾지 못하고
다음 에러에서만 볼 수 있었습니다. 콘솔 사용이 익숙해지면 더 알아보겠습니다.(해당 에러는 단순 오타 에러입니다. ㅎㅎ;;)
이처럼 호출 스택은 다음과 같습니다.
anonymous 함수는 처음 실행 시의 전역 컨텍스트(global context)를 의미합니다. 밑의 그림에서 볼 때 console.log('시작')과 같은 것입니다. 함수가 호출되었을 때 생성되는 환경이고 실행이 완료되면 지워집니다.
function run(){
console.log('3초 후 실행')
}
console.log('시작')
setTimeout(run, 3000)
console.log('끝')
3초 뒤에 run 함수가 실행됩니다. 이를 구조적으로 이해하려면 이벤트 루프, 테스크 큐(task queue), 백그라운드(background)를 알아야 합니다.
백그라운드
위의 setTimeout 같은 타이머나 이벤트 리스너들이 대기하는 곳입니다. 자바스크립트가 아닌 다른 언어로 작성되며 여러 작업을 동시에 실행할 수 있다고 합니다.
테스크 큐
이벤트 발생 후, 백그라운드에서는 테스크 큐로 타이머나 이벤트 리스너의 콜백 함수를 보냅니다.
호출 스택에 들어간 반대로 실행되기 때문에 setTimeout 가 먼저 실행됩니다. setTimeout이 실행되면서 run 콜백과 타이머를 백그라운드로 보내고, setTimeout은 호출 스택에서 빠집니다. 이후 백그라운드에서 3초가 지나고 run 함수를 테스크 큐로 보냅니다. 즉, 백그라운드의 작업이 완료되었다고 할 수 있습니다. 참고로 테스크 큐는 여러 개로 이루어져 있습니다.
호출 스택의 이펜트가 모두 실행되면
이벤트 루프가 run 콜백을 테스크 큐에서 꺼내 호출 스택으로 올립니다.
호출 스택에 함수들이 너무 많으면 정해진 타이머 시간 후에도 실행되지 않을 수 있다고 합니다. 이벤트 루프는 호출 스택이 비어 있을 때만 테스크 큐에 있는 함수를 가져옵니다.
논 블로킹 I/O
위에서 작성된 코드는 동시에 실행될 수 없습니다. 하지만 자바스크립트에서 돌아가는 것이 아닌 I/O 작업은 동시에 처리될 수 있습니다. 노드가 작업을 동시에 처리될 수 있는 I/O 작업들을 묶어서 백그라운드로 넘기면 시간을 절약할 수 있습니다.
function lonRunningTask() {
//오래 걸리는 작업
console.log('작업 끝');
}
console.log('시작');
setTimeout(longRunningTask, 0);
console.log('다음 작업');
setTimeout을 주어 백그라운드에 보내 동시에 작업하도록 하는 원리입니다.
싱글 스레드
싱글 스레드란 말 그대로 스레드가 하나인 것을 의미합니다. 그러므로 코드가 동시에 실행될 수 없습니다.
스레드를 이해하기 위해서 프로세스를 알아봅시다.
프로세스는 운영체제에서 할당하는 작업의 단위로서 프로세스 간에는 메모리 등의 자원을 공유하지 않아 독립적입니다.
스레드는 프로세스 내에서 실행되는 흐름의 단위입니다. 여러개를 생성해 동시에 작업할 수 있고 부모 프로세스의 자원을 공유합니다.
노드를 생성하면 프로세스가 하나 생성되고 그 프로세스에 스레드들을 생성합니다.
노드가 싱글 스레드로 동작하지 않는 경우는 스레드풀(Thread Pool)과 워커 스레드(Worker Thread) 두 가지 입니다.
스레드 풀은 프로그램 실행에 있어서 동시성을 가지기 위한 소프트웨어 디자인 패턴이고
워커 스레드는 여러 병렬 실행에서 동시에 여러 작업을 실행하는 수단이며 멀티 프로세서와 다중 스레드 뿐만 아니라 UI 메인 스레드에서 사용할 필요가 없는 작업을 보조 스레드로 위임하여 애플리케이션의 UI 스레드가 응답하게 할 수 있다고 합니다.
node.js를 시작하기 전에 기초 개념을 정리해 보았는데 모르는 부분과 잊어버린 부분이 상당히 많아서 틈틈히 주요 용어나 기술에 대한 세부적인 공부가 필요하다는 생각이 들었습니다. 앞으로 더 열심히 해야겠네요 ㅎㅎ;;
다음에는 본격적으로 node.js코딩과 환경설정을 해보도록 하겠습니다.
Node.js 교과서: 기본기에 충실한 Node.js 10 입문서
조현영의 책
www.google.com
'Node.Js 정복기' 카테고리의 다른 글
노드 기능 part 2. (0) | 2021.01.13 |
---|---|
노드의 기능 part 1. (0) | 2021.01.11 |
MongoDB 설치 및 기초 (0) | 2021.01.06 |