환경
- Visual Studio Code
- Node v10.16.3
- Window OS
Node.js란
자바스크립트 런타임
노드는 자바스크립트 런타임이다.
런타임 : 특정 언어로 만든 프로그램들을 실행할 수 있는 환경
그렇기에 노드는 자바스크립트로 만든 프로그램을 컴퓨터에서 실행할 수 있게 해준다.
노드는 V8 엔진과 더불어 libuv라는 라이브러리를 사용한다.
여기서 libuv 라이브러리는 노드의 특성인 이벤트 기반, 논블로킹 I/O 모델을 구현하고 있다.
V8, libuv는 C와 C++로 구현되어 있다.
이벤트 기반
이벤트 기반 : 어떤 이벤트가 발생할 때 미리 저장해둔 작업을 수행하는 방식
ex) 클릭 이벤트, 네트워크 요청, etc
이런 이벤트 기반 시스템에서는 특정 이벤트가 발생할 때 무엇을 할지 미리 등록해야 한다.
이것을 이벤트 리스너(event listener)에 콜백(callback) 함수를 등록한다고 표현한다.
삭제 버튼을 누르면 경고 창을 띄우도록 하는 것을 예로 들어 보자.
삭제 버튼 이벤트 리스너에 경고 창을 띄우는 콜백 함수를 등록해두면, 삭제 버튼을 누를 때마다 콜백 함수가 실행돼 경고 창이 뜬다.
노드도 이벤트 기반 방식으로 동작한다. 이벤트가 발생하면 이벤트 리스너에 등록해둔 콜백 함수를 호출한다.
발생한 이벤트가 이벤트 리스너에 없거나 발생했던 이벤트를 다 처리하면 노드는 다음 이벤트가 발생할 때까지 대기한다.
이벤트 기반 모델에는 이벤트 루프라는 개념이 등장한다.
여러 이벤트가 동시에 발생 될 경우도 있을 것이다. 이때 어떤 순서로 콜백 함수를 호출할지를 이벤트 루프가 정한다.
논블로킹 I/O
블로킹 : 어떤 작업이 실행되면 그 작업이 끝날때 까지 기다린 후 다음 작업을 실행한다.
논블로킹 : 어떤 작업이 실행되더라도 끝날때 까지 기다리는 것이 아닌 바로 다음 작업을 실행한다.
이벤트 루프를 활용해서 오래걸리는 작업을 효율적으로 처리할 수 있다.
오래 걸리는 함수를 백그라운드로 보내서 다음 코드가 먼저 실행되게 하고, 짧게 끝나는 작업들이 다 끝나면 백그라운드에 있던 오래 걸리는 함수를 가져와 실행시킨다.
1
2
3
4
블로킹 논블로킹
-- --
-- --
-- --
논블로킹이 위의 상황을 봤을때 같은 작업을 더 짧은 시간에 끝낼 수 있는 것을 확인할 수 있다.
하지만 싱글 스레드라는 한계 때문에 자바스크립트의 모든 코드가 이 방식으로 시간적 이득을 보는 것인 아니다.
현재 노드 프로세스 외의 다른 컴퓨팅 자원을 사용할 수 있는 I/O 작업이 주로 시간적 이득을 많이 본다.
싱글 스레드
노드는 싱글 스레드 기반이다. 일이 주어지면 혼자서 처리해야 한다는 뜻이다.
혼자 처리하기 때문에 고장나거나 느려진다면 매우 문제가 심각해진다.
논블로킹의 중요성 -> 싱글 스레드인데 블로킹이라면 다음 작업을 지금 작업이 끝날때 까지 처리하지 못해 매우 비효율적일 것이다.
평범한 음식점을 생각해보자. (점원은 1명밖에 없다고 가정하자. 싱글 스레드)
1
2
3
4
5
6
7
점원이 A손님으로부터 주문을 받는다. (삼겹살 1인분 주세요~!)
점원은 주방에게 주문을 전달한다. (3번 테이블 삼겹살 1인분이요.)
점원은 B손님으로부터 주문을 받는다. (오겹살 1인분 주세요~!)
생략
이 상황이 우리가 흔히 겪는 음식점이다.
이런 상황을 싱글 스레드 논블로킹이라고 한다.
반대로 싱글 스레드 블로킹 상황을 알아보자. (매우 비효율적)
1
2
3
4
5
6
7
8
9
점원이 A손님으로부터 주문을 받는다. (삼겹살 1인분 주세요~!)
점원은 주방에게 주문을 전달한다. (3번 테이블 삼겹살 1인분이요.)
점원은 주방에서 삼겹살 1인분이 나올때 까지 주방에서 기다린다. (블로킹, 대기 상태)
점원은 B손님으로부터 주문을 받는다. (오겹살 1인분 주세요.)
생략
이런 일이 흔치 않지만 어떻게 봐도 비효율적이라는게 느껴진다.
그렇다면, 멀티 스레드 논블로킹이 제일 좋지 않나? 라는 생각이 들 수 있다.
각자의 장단점이 있다. 멀티 스레드를 알아보자.
1
2
3
4
5
6
7
A점원이 A손님으로부터 주문을 받는다. (삼겹살 1인분 주세요~!)
A점원은 주방에게 주문을 전달한다. (3번 테이블 삼겹살 1인분이요.)
B점원은 B손님으로부터 주문을 받는다. (오겹살 1인분 주세요~!)
생략
멀티 스레드 특징
-
충분히 많은 수의 점원이 있다면 모든 손님에게 1:1 대응을 할 수 있다.
-
어떤 점원이 문제가 생겨도 다른 점원이 대신 일을 할 수 있다.
-
하지만 손님의 수가 늘어날수록 점원의 수가 늘어난다.
-
손님 수가 줄어들면 노는 점원이 있기 마련이다.
-
점원을 새로 고용하거나 해고하는 데 비용이 발생한다.
서버로서의 노드
-
노드가 싱글 스레드, 논블로킹 모델을 사용하므로 노드 서버 또한 동일한 모델일 수밖에 없다.
-
따라서 노드 서버의 장단점은 싱글 스레드, 논블로킹 모델의 장단점과 크게 다르지 않다.
-
싱글 스레드이기 때문에 컴퓨터 자원을 적게 사용한다. 하지만 CPU 코어를 하나밖에 사용하지 못한다.
-
노드 서버는 I/O 가 많은 작업에 적합하다. libuv 라이브러리를 사용하여 I/O 작업을 논블로킹 방식으로 처리한다.
-
따라서 스레드 하나가 많은 수의 I/O를 혼자서 감당할 수 있다.
-
하지만 CPU 부하가 큰 작업에는 적합 ❌❌ -> 모두 스레드 하나에서 처리되기에 스레드 하나가 감당하기 어렵다.
-
싱글 스레드이기 떄문에 에러를 잘 잡아줘야 한다. 에러를 제대로 처리하지 못하면 서버 전체가 멈춘다. (싱글 스레드)
-
웹 서버(Apache,nginx, etc)가 내장되어 있다. 하지만 서버 규모가 커지면 nginx 등의 웹 서버를 둬서 노드 서버와 연결해야 한다.
-
웹 브라우저도 자바스크립트를 사용하기 때문에 자바스크립트로 하나의 웹 사이트를 개발할 수 있다.
-
JSON이 자바스크립트 형식이기에 노드에서는 쉽게 처리 가능하다.
-
이러한 특징때문에 노드는 개수는 많지만 크기는 작은 데이터를 실시간으로 주고 받는 데 적합하다.
ex) 실시간 채팅 애플리케이션 or 주식 차트 or JSON 데이터를 제공하는 API 서버
Reference
- Node.js의 교과서 (조현영 지음)