NodeJS

[Node.js] Node.js의 특성

갓태희 2021. 5. 28. 17:08

노드의 3가지 특성인 이벤트 기반, 논 블로킹 I/O, 싱글 스레드에 대해서 알아보겠습니다.

이벤트 기반

대부분의 프로그램(웹페이지, 게임, 한글과 컴퓨터)들은 잘 생각해보면 모두 이벤트 기반으로 동작을 하는것을 알수있습니다. 이벤트 기반은 사용자와 상호작용 하는것을 말하는데 실제 예를 들어가면서 설명하겠습니다.

우리가 가장 많이 접하는 이벤트로 마우스클릭이 있습니다. 모든 프로그램에 있는 닫기버튼, 최소화버튼, 최대화버튼은 각각 버튼을 클릭하면 닫기, 최소화, 최대화라는 기능을 실행합니다. 언제 어느때나 클릭해도 같은 버튼들은 같은 기능을 제공합니다. 이런게 가능한 이유는 콜백 함수를 메모리에 등록시켜놓았기 때문인데 이 콜백함수는 각각의 버튼에서 닫기, 최소화, 최대화의 기능들을 수행합니다. 이러한 기능을 수행하는 콜백함수들이 메모리에 등록되어있고 버튼 클릭이라는 이벤트가 사용자에 의해 일어났을때 콜백함수가 실행되어지며 그 콜백함수의 내용이 각각 닫기, 최소화, 최대화를 수행하는 코드로 개발자들이 미리 작성을 해놓았기때문에 이러한 일이 정상적으로 일어날수 있는것입니다. 이렇게 우리가 흔하게 접하지만 너무나 당연해서 개발자가 아닌이상 혹은 프로그램을 배우는 사람이 아니면 이러한 일이 내부적으로 일어나고있다는 사실을 모르고 사용할것입니다.

또 다른 예로 우리가 네이버 홈페이지를 들어가기위해 브라우저 주소창에 www.naver.com이라는 주소를 치면 브라우저는 네이버 DNS를 통해서 IP주소를 따러가고 방화벽을 뚫고 서버에서 응답을 받아서 다시 DNS를 통해 최종적으로 우리의 브라우저에 네이버 홈페이지를 띄워주는 과정을 0.1ms만에 수행하는데 이러한 각각의 과정들이 모두 콜백함수를 통해 이루어지며 우리는 주소창에 입력 한번으로 이러한 기능들을 알게모르게 사용하고 있었습니다.

논 블로킹 I/O

논블로킹은 동시라는 말이 아니며, 노드는 블로킹이면서 동기이고 논블로킹이면서 비동기이다. 많은 사람들이 비동기이면서 논블로킹일때 노드 프로그램이 동시에 돌아간다는 오해를 합니다. 이때 동기는 코드를 순서대로 실행, 비동기는 코드가 순서대로 실행되지 않는것을 의미하며, 코드가 순서대로 실행되지 않는것도 어떠한 규칙을 가지고 있습니다. 이 내용은 실행컨텍스트와 이벤트루프때 자세히 더 다루겠습니다.

싱글 스레드

우리가 자주 사용하는 크롬을 작업관리자로 보게되면 크롬 프로세스 하나와 그 밑에 많은 스레드들이 있는것을 볼수 있는데 크롬 창이 프로세스 그 창안에있는 각각의 탭들이 스레드라고 생각하면된다. 이처럼 노드가 싱글스레드다 라는 말은 노드 프로세스 안에 탭을 하나밖에 내가 못띄우는것이라는 말이다. 노드를 처음 실행시킬때 총 4개의 스레드가 뜨지만 그중에 내가 직접 제어할수있는 스레드가 한개밖에 없기때문에 싱글스레드라고 말을 하는것이다. 그래서 노드는 원래는 멀티스레드이지만 싱글스레드라고 말을 합니다. 다른 3개의 스레드는 코드를 동시에 돌릴 준비를 하고있는 스레드이며 어떤 특정조건을 만족하는 순간 코드를 동시에 돌리기 시작하며 그전까지는 대기를 한다.

싱글 스레드와 멀티 스레드의 차이점을 좀 더 쉽게 알아보겠습니다 싱글 스레드에서는 내가 크롬에서 유튜브, 인스타를 하려고하면 유튜브를 보고있다가 유튜브를 끄고 인스타를 보러가야하는데 멀티 스레드는 탭 2개 띄워놓고 유튜브를보면서 인스타의 알림들을 실시간으로 바로바로 볼수있다 이게 싱글 스레드와 멀티스레드의 차이이다.

멀티스레드는 실시간으로 바로바로 확인할수있다는 장점이 있지만 그만큼 프로그래밍 자체가 어렵다 그래서 노드는 "한가지 일만이라도 빠르게 잘하겠다"라는 방식을 채택했으며 그 방식이 싱글스레드 방식이다.

스레드 하나당 CPU 코어 1개를 잡아먹는데 16코어 32코어 처럼 더많은 코어를 써도 노드는 싱글스레드이기때문에 32코어 처럼 코어가 많다해도 1개의 코어만 쓰고 나머지 31개의 코어는 논다 그래서 한개의 코어만 엄청 뜨겁고 나머지는 얼음처럼 차가울수도 있는 현상이 나타난다.

노드의 스레드방식의 시각화

위의 그림은 점원 3명과 고객3명이 아주 순조롭게 주문을 주고받는 그림을 나타낸다. 하지만 위의 그림에서 만약 점원 2,3이 놀고 점원 1이 고객 2,3까지 커버를 치려면 점원 1번이 매우 힘들어진다. 이것이 노드의 방식이며 싱글 스레드이다. 아주 순조롭게 주문을 주고받는 방식이 멀티스레드 방식이다.

멀티스레드는 분명히 장점이 있다 하지만 그만큼 점원을 많이 고용해야하기때문에 인건비가 많이든다.

점원 1이 매우 힘들다고 손님을 한명만 받아버리면 그것도 또 안될노릇이다.

그래서 노드는 위의 그림처럼 우선 고객들의 주문을 받아놓고 주방에서 음식이 모두 완료가 되면 차례로 음식을 가져다주는 방식을 택했다.

정리

앞서 말했듯이 노드는 분명히 실행시킬당시 4개의 스레드가 존재하지만 내가 컨트롤할수있는 스레드가 한개이기때문에 멀티스레드가 있지만 싱글스레드이다. 하지만 노드 14부터는 멀티스레딩을 가능하게 해주었다. 멀티스레딩이 그동안 없었기때문에 멀티스레딩 기능을 추가해준것일뿐 멀티스레딩을 적극 권장을 하기위해 추가한것은 아니다.