본문 바로가기
인턴(2023.07. ~ 2023.12.)/스크립트 송출 서버 개발

Node.js 란?

by xladmt 2023. 8. 8.

Node.js란?

 

Node.js는 Chrome V8 JavaScript 엔진으로 빌드 된 JavaScript 런타임이다. 런타임이란 특정 언어로 만든 프로그램을 실행할 수 있는 환경을 의미한다. 이전까지 Javascript는 웹 브라우저에서만 사용되는 스크립트 언어였지만, 구글의 V8 엔진 출시로 속도 문제가 많이 해결되었고 그 결과로 웹 브라우저 외의 환경에서 Javascript를 실행할 수 있는 프로그램 Node.js이 개발되었다. Node.js에서는 JavaScript으로 OS의 기능에 액세스하는 프로그램을 짤 수 있다. 즉, 브라우저에서 동작하고 있을 때는 되지 않았던 자유로운 파일의 읽기, 쓰기나 네트워크 통신 등의 OS의 기능을 다룰 수 있다.

 

Node.js는 확장성이 있는 네트워크 어플리케이션 개발에 사용되는 소프트웨서 플랫폼이다. 자바스크립트를 활용하며, Non-blocking I/O와 단일 스레드 이벤트 루프를 통한 높은 처리 성능을 가지고 있는 것이 특징이다.

 

내장 HTTP 서버 라이브러리를 포함하고 있어 웹 서버에서 아파치 등의 별도 소프트웨어 없이 동작하는 것이 가능하며, 이를 통한 웹 서버의 동작에 있어 더 많은 통제에서 벗어나 여러 가지 기능을 가능하게 한다.

 

Node.js 특징

 

- 싱글스레드 모델

Node.js는 싱글 스레드, 논 블로킹 모델로 싱글 스레드가 혼자서 일을 처리하지만 들어오는 요청 순서가 아닌 논블로킹 방식으로 이전 작업이 완료될 때까지 대기하지 않고 다음 작업을 수행한다.

 

* 프로세스 : 운영체제에서 할당하는 작업의 단위이다. 노드나 웹 브라우저 같은 프로그램은 개별적인 프로세스이다. 프로세스 간에는 메모리 등의 자원을 공유하지 않는다.

* 스레드 : 스레드는 프로세스 내에서 실행되는 흐름의 단위이다. 프로세스는 스레드를 여러 개 생성해 여러 작업을 동시에 처리할 수 있다. 스레드들은 부모 프로세스의 자원을 공유한다. 같은 주소의 메모리에 접근 가능하므로 데이터를 공유할 수 있다.

 

Node.js 프로세스가 실행되면 내부적으로 스레드를 여러 개 생성한다. 하지만 이 중에서 우리가 직접 제어할 수 있는 스레드는 단 한 개이기 때문에 Node.js를 싱글 스레드라고 부른다. 그리고 나머지 스레드들은 내부적으로 블로킹되는 작업들(file I/O, DB 등)을 수행하고, 그 콜백을 이벤트 루프에 등록한다.

 

이렇게 Node.js는 새로운 스레드를 생성하거나 멀티 스레드를 관리하는 데 필요한 작업(lock)을 수행하지 않아도 되기에 다른 언어에 비해 적은 오버헤드를 가지고 있고, 확장성이 크며 개발하기가 쉽다. 다만 블로킹 때문에 CPU 연산을 많이 요구하는 작업에는 적합하지 않다는 단점을 가지고 있다.

 

 

- Non-blocking I/O

블로킹이란, Node.js 프로세스에서 추가적인 JavaScript의 실행을 위해 JavaScript가 아닌 작업이 완료될 때까지 기다려야만 하는 상황이다. 반대로 논블로킹은 추가적인 JavaScript 실행을 위해 JavaScript가 아닌 작업이 완료될 때까지 기다리지 않아도 되는 상황을 말한다.

 

이벤트 루프를 잘 활용하면 오래 걸리는 작업을 효율적으로 처리할 수 있다. 작업에는 동시에 실행될 수 있는 작업과 동시에 실행될 수 없는 작업 두 가지 종류가 있다. 특히 파일 시스템 접근, 네트워크를 통한 요청 작업은 입력(Input)/출력(Output)의 일종이며, 이러한 작업을 할 때 노드는 비동기 방식으로 블로킹을 만들지 않게 끔(논 블로킹) 처리한다. 비동기란, 이전 작업이 완료될 때까지 대기하지 않고 동시에 작업을 수행한다. 반대로 동기는 이전 작업이 끝나야만 다음 작업을 수행한다.

 

자세하게 이야기하면, 함수 호출 시 당장 실행하는 것이 아니라(동기->블로킹) 일단 어느 곳에 쌓아 놓고 동시에 요청을 처리하고(비동기->논 블로킹) 요청이 완료된 순서대로 처리(스택 이용) 한다는 말이다. 

 

// 블로킹 예시
const fs = require('fs');
const data = fs.readFileSync('/file.md'); // 파일을 읽을 때까지 여기서 블로킹됩니다.
console.log(data);
moreWork(); // moreWork 는 console.log(data)가 실행되고 실행됩니다.

 

// 논-블로킹 예시
const fs = require('fs');
fs.readFile('/file.md', (err, data) => {
  if (err) throw err;
  console.log(data);
});
moreWork(); // moreWork();는 console.log 이전에 실행될 것입니다.

 

위의 블로킹 예시에서는 file.md를 다 읽을 때까지 전체 JavaScript 시스템이 멈추지만, 아래 논 블로킹 예시에서는 비동기적으로 실행되기에 전체 JavaScript 시스템이 멈추지 않고 moreWork()가 먼저 실행된다. 그리고 file.md를 다 읽고 나서 fs.readFile의 두 번째 파라미터로 들어간 콜백(callback) 함수가 실행된다. 여기서 콜백 함수란 어떤 이벤트(이 경우에서는 file I/O)가 끝나고 나서 실행되는 함수를 말한다.

 

 

- 이벤트 기반

이벤트 기반(Event-driven)이란 이벤트가 발생할 때 미리 지정해둔 작업을 수행하는 방식을 의미한다. 즉, 이벤트 기반 시스템에서는 특정 이벤트가 발생할 때 무엇을 할지 미리 등록해두고, 이를 이벤트 리스너에 콜백함수를 등록한다. 이후 이벤트가 발생하면 리스너에 등록해둔 콜백함수를 호출하며, 이벤트가 끝난 후 노드는 다음 이벤트가 발생할 때까지 대기한다.

JavaScript는 싱글 스레드 기반의 언어이기 때문에 단 한 개의 Call Stack을 가지고 있다. 따라서 이 Call Stack의 상태를 잘 유지해줘야 한다. 만일 엄청나게 시간이 오래 걸리는 연산이 Call Stack에서 돌아가고 있다면, 다른 JavaScript 코드들은 실행되지 못하고 블로킹 되어 있을 것이다. 따라서 블로킹을 일으키는 이벤트(DOM, AJAX 등)들은 Web APIs들을 해 메인 스레드를 블로킹 시키지 않고 비동기적(Asynchronous)으로 실행된다. 이 이벤트들은 모두 콜백 함수를 지니고 있는데, 콜백 함수는 특정 이벤트가 발생했을 때 수행되는 함수를 의미한다. 그리고 이 콜백 함수들은 백그라운드에서 이벤트 처리가 끝난 뒤 태스크 큐(Task Queue)에 순차적으로 쌓이게 되고, 이벤트 루프는 Call Stack이 비어 있을 때 태스크 큐에서 콜백을 꺼내 Call Stack에 올리는 역할을 수행한다.

 

*이벤트 루프

이벤트 루프(event loop)는 호출할 콜백 함수들을 관리하고, 호출된 콜백 함수의 실행 순서를 결정하는 역할을 담당한다. 노드는 이벤트가 종료될 때까지 이벤트 처리를 위한 작업을 반복하므로 루프(loop)라고 부른다.

 

 

Node.js 장단점

 

[장점]

 - 멀티 스레드 방식에 비해 적은 컴퓨터 자원 사용

 - I/O 작업이 많은 서버로 적합

 - 웹 서버가 내장되어 있음

 - 자바스크립트를 사용함

 - JSON 형식과 쉽게 호환됨

 

[단점]

 - 기본적으로 싱글스레드라 CPU 코어를 하나만 씀

 - CPU 작업이 많은 서버로 부적합

 - 스레드가 하나쁜이므로 더 주의가 필요. 이 스레드가 죽어버리면 모든게 끝

 - 서버 규모가 커졌을 때 서버를 관리하기 어려움. 

 

 

Node js 예제

 

const http = require('http');
var microtime = require('microtime');

const hostname = '192.168.0.114'; // http://192.168.0.114:3000/
const port = 3000;
console.log("aaaa");
const server = http.createServer(function(req, res){
    res.statusCode = 200;
    // res.writeHead(200);
    res.end(String(microtime.now()));
});

server.listen(port, hostname, () => {
    console.log(`Server running at http://${hostname}:${port}/`);
});

console.log("dddd");

 

 

 

[참고]

https://hanamon.kr/nodejs-%EA%B0%9C%EB%85%90-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0/

 

Node.js 노드 개념 이해하기 자바스크립트 JavaScript 런타임 이벤트

Node.js 노드 개념 이해하기 JavaScript 런타임 - 노드는 다양한 자바스크립트 애플리케이션을 실행할 수 있으며, 서버를 실행하는데 제일 많이 사용된다. 이벤트 기반 이벤트 루프 논블로킹 I/O 싱글

hanamon.kr

https://velog.io/@shinsw627/Node.js%EB%A5%BC-%ED%8C%8C%ED%97%A4%EC%B9%98%EC%9E%90-%EC%9E%91%EB%8F%99-%EC%9B%90%EB%A6%AC-%EC%8B%B1%EA%B8%80%EC%8A%A4%EB%A0%88%EB%93%9C-%EB%85%BC%EB%B8%94%EB%A1%9C%ED%82%B9IO-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EA%B8%B0%EB%B0%98

 

Node.js를 파헤치자 - 작동 원리, 싱글스레드, 논블로킹I/O, 이벤트 기반

Node란? Node.js는 Chrome V8 Javascript 엔진으로 빌드된 Javascript 런타임이다. - by node 공홈 런타임이란 특정 언어로 만든 프로그램을 실행할 수 있는 환경을 의미한다. 이전까지 Javascript는 웹 브라우저에

velog.io

https://engineer-mole.tistory.com/326

 

Node.js의 설명과 Node.js를 사용하는 이유

※ 일본의 한 블로그 글을 번역한 포스트입니다. 오역 및 의역, 직역이 있을 수 있으며 틀린 내용은 지적해주시면 감사하겠습니다. 기초 : JavaScript의 특징 먼저 JavaScript와 다른 프로그래밍 언어

engineer-mole.tistory.com

 

'인턴(2023.07. ~ 2023.12.) > 스크립트 송출 서버 개발' 카테고리의 다른 글

Node.js http 모듈  (0) 2023.08.17
인메모리 컴퓨팅  (0) 2023.08.10
Node.js - Cluster  (0) 2023.08.09
HTTP와 HTTPS  (0) 2023.08.09
웹 서비스 구조  (0) 2023.08.08