Computer Engineering/Node.js

NodeJS 정리하기 ( =이것만 사용하면 프론트/백 모두 구현 가능함)

soohey 2022. 8. 23. 00:56

시작하기 앞서 NodeJS는 웹 서버가 아니라 자바스크립트 실행환경이라는 점을 인식하자. NodeJS로도 서버를 구성할 수 있다! 고 해야 맞는 말인 듯하다. ( 보통 프론트, 백을 구분하는데 NodeJS로는 둘 다 노드 내에서 구현 가능함.. 풀스택하기 참 쉽다..응.. )

NodeJS는 이벤트 기반, 논 블로킹 I/O모델을 사용하며 싱글스레드 방식을 채택했다.

이벤트 기반 동작, 싱글 스레드에 주목해서 정리할 것이다.

프로세스

  • 운영체제로부터 자원을 할당받는 작업 단위

스레드

  • 할당받은 자원을 이용하는 실행 단위
  • 하나의 프로세스를 여러 스레드를 가지고 자원을 공유한다.

하나의 스레드는 한 번에 단 하나의 동작만 수행 가능하다.

그럼 자연스럽게 멀티스레드는 한번에 여러 가지 동작이 가능할 것이다. (스레드가 여러 개니까)

애플리케이션 하나가 프로세스고, 그 안에서의 일어나는 분기 처리를 스레드라고 표현한다.

NodeJS는 싱글 스레드를 사용하는데 이유는 Blocking 방식과 멀티스레드의 단점을 보완하기 위해서이다.

Blocking I/O란

  • 하나의 프로세스가 어떤 자원을 사용하고자 할 때 다른 프로세스가 이미 사용중이라면, 사용이 끝날 때까지 기다리는 것을 말한다.
  • 기다리는 상태를 Blocked되었다고 표현하며 (흔히 말하는 불록 상태) 아무것도 하지 않는 상태이다.
  • NodeJS는 논블로킹 방식으로 기다리지 않고 요청이 오는대로 수행을 시작한다. 당연히 논블로킹 방식이 더 빠르게 작업이 가능하다.
  • 우리는 setTimeout(콜백, 0), setImmediate(콜백) 같은 내장 객체로 논블로킹을 구현한다.

멀티 스레드의 단점

  • 하나의 프로세스는 보통 1개의 요청만을 처리하는데, 다수의 요청이 들어온다면 어떻게 해야 할까? 이럴 때는 멀티스레드라는 개념을 사용한다.
  • 스레드 여러개가 동시에 실행되어 요청을 처리한다는 개념이다.
  • 멀티스레드를 사용하면 많은 자원을 필요로 하게 되고 여러 스레드가 CPU 점유를 위해 기다려야 하는 문제가 생긴다.
  • 또한 Blocking으로 인해 아무것도 안하고 기다리게 되면 스레드 지연의 문제가 생긴다.
  • 만약 스케줄링을 시도한다면 Context Switch 비용이 발생하게 된다. 스케줄링 또한 CPU를 통한 연산이기 때문이다.
  • 물론 장점도 있다...(이건 다음글로) 이것은 선택의 문제.. 여담이지만 실무에서는 좀 더 유연하고 가벼운 서버일 경우 NodeJS로 만드는 경향이 있다고 함. 반대로 업무 복잡도가 높은 경우는 지양함

싱글 스레드와 이벤트 기반 논 블로킹 I/O

  • 멀티스레드의 위 같은 단점 때문에 NodeJS는 싱글 스레드를 선택하였다.
  • 노드는 싱글스레드를 가지기에 I/O 작업이 시작되면 처리완료에 대한 응답을 기다리지 않고 바로 다음 작업을 실행한다. (비동기이므로 Blocking이 없음) 그러므로 작업이 완료될 때까지 기다릴 필요가 없어진다.
  • 대신 특정 이벤트 발생 시 수행할 작업을 등록하여, I/O 작업이 종료되면 이벤트를 감지해 등록된 작업을 수행한다.
  • 가볍고 효율적인 자원 사용이 가능해진다.
  • 다만 오류 발생시 처리해줄 사람이 없어 문제가 발생할 수 있고, CPU 코어를 모두 활용하지 못하는 단점이 있다.

사실은 노드 내에 여러 스레드를 가지지만, 직접 제어하여 자바스크립트를 실행하는 스레드는 1개여서 싱글 스레드라고 부른다. (Thread Pool이라고 함. 클라이언트 요청은 한 스레드에서만, 요청에 대한 작업은 멀티스레드로 실행함)

여기서 말하는 하나의 스레드는 이벤트 루프를 돌 때 사용된다.

노드는 스레드를 늘리는 대신, 프로세스 자체를 복사해 여러 작업을 동시에 처리하는 멀티 프로세싱 방식을 선택했다. (NginX에서 cluster 모듈과 pm2 패키지를 이용해 멀티 프로세싱이 가능하게 한다. 주로 운영/배포 자동화에 사용한다. )

 

Nginx를 이용한 무중단 배포 시스템은 진짜 무중단일까?

오늘의 주제는 Github와 Nginx를 통해 만들어진 무중단 배포 시스템이 정말로 무중단일까?이다. 보통 Nginx로 프로그램을 배포시키고, 반영할 개선사항이 존재하면 Github를 통해 반영시킨 후, pm2를 통

soohey.tistory.com

 

Node.js의 스레드 | devlog.akasai

앞서서 Node.js의 비동기처리에 대한 전반적인 내용을 정리했다. 이번엔 싱글만레드의 특징을 정리하려 한다. + 정말… 해도해도 공부할 내용이 끝이 없다. 얼마나 대충쓰고 있었는지 반성한다…

akasai.space

이벤트 기반 동작 방식이란?

  • NodeJS는 V8이라는 자바스크립트 엔진과 libuv라는 비동기 작업이 가능한 라이브러리를 가진다.
  • libuv는 이벤트 발생시 미리 지정한 작업을 수행하도록 하여 비동기 작업을 수행한다.
  • 이것을 이벤트 리스너에 콜백 함수를 등록한다고 표현함
  • 여러 이벤트가 동시 발생시 어떤 순서로 콜백함수를 호출할지를 지정해야 하는데 이를 이벤트 루프가 지정한다.

이벤트 루프

  • 비동기 방식은 특정 동작 실행 후 이후에는 관심을 끊는다.
  • 대신 동작이 완료될 경우 다음에 실행할 함수를 미리 등록할 수 있음
  • 동작이 완료되면 등록된 함수를 실행한다.

마지막으로 NodeJS의 장점과 단점 정리하면서 특징 되짚어 보기~

장점

  • 싱글 스레드 기반의 비동기 처리로 매우 빠른 고성능 서비스
  • pm2 restart 시간이 매우 짧아 빠른 배포나 업그레이드가 가능
  • 프런트와 백엔드의 통합. 프런트 개발자도 서버 백엔드 개발하기에 쉽다고 함
  • 싱글 스레드라 스레드 간의 동기화 처리 같은 복잡한 과정이 필요 없음 (이는 단점도 될 수 있음)
  • socket.io API 사용 시 싱글 스레드 기반 멀티 플렉싱을 기반으로 대용량 사용자에 대한 푸시 처리가 가능하다.
  • npm을 통한 웬만한 기능이 모듈로 구현되어 있음 (굉장히 편함.. 루비 못지않다)

단점

  • 싱글스레드다 보니 하나의 작업이 복잡도가 높거나 시간이 많이 소요되면 전체 시스템의 성능이 급격히 떨어짐 (하나가 죽으면 전체가 죽어버림)
  • 코드 가독성이 낮은 편 (콜백 중첩 때문이다. 콜백 지옥이라고도 함. )이라 유지보수가 어렵다.
  • 스크립트 언어 특성상 언어가 수행되어야 에러가 발생하는지 확인 가능함. 에러 발생 시 잘 죽음
  • 멀티 코어 머신에서 CPU 사용을 최적화할 수 없음. CPU 사용률이 높은 어플리케이션에서는 추천 안 함 (설계 시 클러스터 모듈을 이용해 하나의 서버에서 여러 노드 프로세스를 사용하도록 해야 함)
  • 세션 등을 공유할 때 redis 같은 추가 인프라가 필요하다.

-> 정리하자면 개발은 쉬운데 운영에서 테스트/장애 대응/디버깅이 어려움

참고

https://hyoveemo.tistory.com/33

 

Node js 의 장점과 단점

Node js 의 장점과 단점 장점 성능 관점 싱글 스레드 기반 비동기 IO처리로 매우 빠른 고성능 서버이다. CPU intensive하지 않고, 많은 Connection을 동시에 처리해야 하는 상황에서 nodejs의 성능이 좋다.

hyoveemo.tistory.com

https://node-js.tistory.com/27

 

Node.js란? Node.js 특징 정리(이벤트 기반, 논 블로킹 I/O 모델)

평소 Node.js를 이용해 백엔드를 개발했지만... NodeJS에 대해 단순히 이벤트 기반이고 비동기식이다라고 밖에 모르고 사용했었던 것 같아 자신에게 반성하며 장단점과 특징에 대해 자세하게 정리

node-js.tistory.com