노드 공식 사이트에서 다음과 같이 노드를 설명하고 있다.
Node.js는 Chrome V8 Javascript 엔진으로 빌드된 Javascrpit 런타임입니다.
서버란 네트워크를 통해 클라이언트에 정보나 서비스를 제공하는 컴퓨터 혹은 프로그램.
브라우저가 url로 해당 서버 컴퓨터의 위치 파악 -> 요청 -> 서버 컴퓨터가 HTML 페이지 전송 -> 브라우저가 HTML 페이지 띄움.
런타임이란 특정 언어로 만든 프로그램들을 실행할 수 있는 환경.
즉, 노드는 자바스크립트의 실행기라고 볼 수 있다.
[노드의 내부 구조]
노드는 V8 엔진과 libuv라는 라이브러리를 사용한다.
이것들은 C와 C++로 이루어져 있지만. 노드가 알아서 자바스크립트 -> C or C++로 변환해 준다.
추가로 libuv는 이벤트 기반, 논 블로킹 I/O 모델이라는 노드의 특성을 구현하고 있다.
이벤트 기반이란 이벤트가 발생할 것을 대비해 미리 작업을 지정해둔 다음, 해당 이벤트가 발생했을 때 미리 지정해둔 작업을 수행하는 것.
(이벤트 ex -> 클릭, 네트워크 요청 등)
이벤트 기반 시스템에서 특정 이벤트가 발생할 때 무엇을 할지 미리 등록하는 것을 이벤트 리스너에 콜백 함수를 등록한다고 표현한다.
ex) A라는 이벤트가 발생 시 B라는 작업을 하는 것 -> A 이벤트 리스너에 B 콜백 함수를 등록한다.
노드는 이벤트 기반이기 때문에 다음과 같이 동작한다.
이벤트가 발생 -> 콜백 함수를 호출 -> 모두 처리했다면 다음 이벤트 발생까지 대기.
노드는 이벤트가 동시에 발생하면 어떤 순서로 콜백 함수를 호출할지를 이벤트 루프로 판단한다.
이벤트 루프 : 이벤트 발생 시 호출할 콜백 함수들을 관리하고, 호출된 콜백 함수의 실행 순서를 결정하는 역할을 담당. 노드가 종료될 때까지 이벤트 처리를 위한 작업을 반복하므로 루프라고함.
백드라운드 : setTimeout() 같은 타이머나 이벤트 리스너들이 대기하는 곳. 자바스크립트가 아닌 다른 언어로 작성된 프로그램이라고 봐도 무방. 여러 작업이 동시에 실행될 수 있음.
태스크 큐 : 이벤트 발생 후, 백그라운드에서는 태스크 큐로 타이머나 리스너의 콜백 함수를 보냄. 정해진 순서대로 콜백들이 줄을 서 있으므로 콜백 큐라고도 부름. 콜백들은 보통 완료된 순서대로 줄을 서 있지만 특정한 경우에는 순서가 바뀌기도 함.
작업에는 두 가지 종류가 있다. (1)동시에 실행될 수 있는 작업과 (2)동시에 실행될 수 없는 작업.
자바스크립트 코드는 (2)에 해당하지만 I/O 작업은 (1)에 해당한다.
논 블로킹이란 이전 작업이 완료될 때까지 대기하지 않고, 다음 작업을 수행하는 것. 단, 작업이 (1) 경우에 해당되어야 한다.
논 블로킹 방식으로 처리 시간을 단축시킬 수 있다.
1, 3, 5는 (1) 경우. 2, 4는 (2) 경우의 작업이라 가정하면
1 2 3 4 5의 순서대로 호출하면 약 5초가 소요된다.
하지만 호출 순서를 바꿔 1, 3, 5를 호출한 뒤 2, 4를 호출하면 1, 3, 5는 논 블로킹으로 처리되기 때문에 약 3초의 시간이 소요된다.
싱글 스레드란 말 그대로 스레드가 1개 존재하는 것을 의미함 -> 이러한 이유 때문에 자바스크립트 코드는 동시에 실행할 수 없다.
프로세스는 운영체제에서 할당하는 작업의 단위. 노드나 웹 브라우저 같은 프로그램은 개별적인 프로세스이다. 프로세스 간에는 메모리 등의 자원을 공유하지 않는다.
스레드는 프로세스 내에서 실행되는 흐름의 단위. 프로세스는 스레드를 여러 개 생성해 여러 작업을 동시에 처리할 수 있다. 스레드들은 부모 프로세스의 자원을 공유한다. 같은 주소의 메모리에 접근 가능하므로 데이터를 공유할 수 있다.
노드가 싱글 스레드라고 이야기하는데 엄밀히 말하면 스레드가 1개인 것은 아니다.
노드 실행 -> 프로세스 1개 생성 -> 내부적으로 스레드를 여러 개 생성함.
But 우리가 직접 제어할 수 있는 스레드가 1개뿐이어서 흔히 노드는 싱글 스레드라고 여겨진다.
노드가 싱글 스레드로 동작하지 않는 두 가지 경우가 있다. 그 두 가지가 스레드풀과 워커 스레드이다.
- 스레드풀은 노드가 특정 동작을 수행할 때 스스로 멀티 스레드를 사용함.
-> 암호화, 파입 일출력, 압축 등- 워커 스레드는 노드 12 버전에서 안정화된 기능으로 노드에서도 멀티 스레드를 사용할 수 있게 되었다. 직접 여러 스레드를 다룰 수 있기 때문에 CPU 작업이 많은 경우 사용 가능.
점원 1명, 손님 여러 명.
점원이 1번 손님의 주문을 받음 -> 주방에서 음식이 나올 때까지 대기 -> 주방에서 음식이 나오면 1번 손님에게 서빙 -> 2번 손님의 주문을 받음.
장점 : 점원이 1명임.
단점 : 일처리가 매우 느리고 비효율 적임.
점원 1명, 손님 여러 명.
점원이 모든 손님에게 주문을 받음 -> 주방에 전달 -> 음식이 나온 순서대로 서빙
즉, 현실에서 음식점의 홀과 비슷하다고 보면 됨.
장점 : 효율 극대화 -> 점원 1명이 모든 일을 처리.
단점 : 점원이 아파서 일을 못하는 경우 모든 일이 마비됨.
점원 수 = 손님 수.
점원 1명이 손님 1명을 1:1로 마킹하는 방식.
즉, 현실에서 백화점 명품관에서 1:1로 손님을 응대하는 방식이라 보면 됨.
장점 : 점원 1명이 아파도 다른 점원으로 대체 가능.
단점 : 손님에게 서빙을 한 후, 손님이 나가고 다른 손님을 받기까지 점원이 할 일이 없음.
멀티 스레드의 장점과 논 블로킹의 장점을 섞음.
점원 수 = 손님 수.
모든 점원이 필요한 곳에 가서 주문을 받고 필요한 곳으로 서빙.
장점 : 가장 좋음
단점 : 프로그래밍이 어려움
때문에 멀티 스레드 방식보단 멀티 프로세싱 방식을 사용함. 또한 I/O 요청에는 멀티 프로세싱이 더 효율적임.
멀티 스레딩 | 멀티 프로세싱 |
---|---|
하나의 프로세스 안에서 여러 개의 스레드 사용 | 여러 개의 프로세스 사용 |
CPU 작업이 많을 때 사용 | I/O 요청이 많을 때 사용 |
프로그래밍이 어려움 | 프로그래밍이 비교적 쉬움 |
노드는 다양한 케이스 중 싱글 스레드, 논 블로킹을 사용한다.
다음 표는 이로 인해 발생하는 서버로서의 노드의 장단점이다.
장점 | 단점 |
---|---|
멀티 스레드 방식에 비해 적은 컴퓨터 자원 사용 | 기본적으로 싱글 스레드라서 CPU 코어를 하나만 사용 |
I/O 작업이 많은 서버로 적합 | CPU 작업이 많은 서버로는 부적합 |
멀티 스레드 방식보다 쉬움 | 하나뿐인 스레드가 멈추지 않도록 관리가 필요함 |
웹 서버가 내장되어 있음 | 서버 규모가 커졌을 때 서버를 관리하기 어려움 |
자바스크립트를 사용함 | 어중간한 성능 |
JSON 형식과 쉽게 호환됨 |