스노우보드 참 좋아하는데 맨날 키보드 앞에만 있네

[NodeJS] 비동기 프로그래밍 본문

개발/NodeJS

[NodeJS] 비동기 프로그래밍

워너-비 2017. 11. 8. 11:40

비동기 프로그래밍




NodeJS를 오늘 처음 공부하기 시작했는데, 비동기 프로그래밍이란 용어가 나와서 정리해본다.


일반적으로 대부분의 어플리케이션은 발생하는 작업들을 중앙 서버에서 처리한다.

이 서버는 Web을 위한 HTTP서버, 소켓 통신을 위한 네트워크 서버 등이 있다.

이러한 중앙집중형태의 서버는 항상 작업처리 성능을 주시해야한다.

왜냐하면 클라이언트 요청이 많을 경우 서버에서 병목 현상이 발생하기 때문이다.

이 병목 현상은 대부분 입출력(IO)에서 발생하는데, 처리 지연으로 인하여 다른 요청을 처리하지 못하면, 계속 대기해야한다.

그래서 대부분의 서버 플랫폼들은 사용자 요청을 쓰레드로 처리하고 있다.



Multi-Thread 방식과 한계


Multi-Thread 방식은 서버에서 요청하는 작업을 쓰레드에서 병렬적으로 처리하는 방식이다.

쓰레드는 서버 CPU 자원을 시분할 형태로 나누어 가짐으로써 독립적 실행이 가능하고, 다른 요청을 동시에 받을 수 있게 한다.


그러나 Multi-Thread 방식이 꼭 성능향상을 보장해주는 것은 아니다

당연히 단점도 존재한다.

Multi-Thread 기반 서버는 클라이언트 요청마다 Thread를 발생시킨다.

따라서 동시 접속자 수가 많을 수록 Thread가 많이 발생하여 그만큼 메모리 자원을 많이 소모한다.

서버 자원은 한계가 있어 일정 이상의 Thread는 발생시킬 수 없다.


따라서 이때 서버를 업그레이드 하거나 Load-Balancing 등으로 분산처리를 통해 문제해결을 해야한다.


Multi-Thread 방식 구조




병렬처리의 대안 : 비동기 처리


동기 방식과 비동기 방식 비교


동기 방식의 처리는 하나의 요청이 처리되는 동안 다른 요청을 처리할 수 없으며, 선행 요청이 완료되어야 다음 요청 처리가 가능한 방식이다.

동기 방식은 IO 처리를 Blocking 하는데 지금까지 이 문제를 Thread로 처리했다.


이 문제를 비동기 방식으로 처리할 수도 있다. 비동기 방식은 하나의 요청 처리가 완료되기 전에 제어권을 다음 요청으로 넘긴다.

따라서 선행요청이 있더라도 이어지는 IO 처리를 Blocking 하지 않으며, 다음 요청을 처리할 수 있다.



Node.js 의 비동기 처리


Node.js 는 비동기 방식으로 병렬 처리를 한다.

비동기 IO를 지원하고, Single-Thread 기반으로 동작하는 서버이다.

따라서 요청을 처리하면서 다음 요청을 받을 수 있다. 또한 병렬 처리를 Thread 로 처리하지 않기 때문에 Multi-Thread가 갖는 문제에서 자유롭다.


Node.js에서의 비동기 처리 구조


Node.js에서 비동기 처리를 이벤트 방식으로 처리한다.

클라이언트 요청을 비동기로 처리하기 위해 이벤트가 발생하고, 서버 내부에 메시지 형태로 전달된다. 서버 내부에서 이 메시지를 Event Loop가 처리한다.

Event Loop가 처리하는 동안 제어권은 다음 요청으로 넘어가며, 처리가 완료된 후 CallBack을 호출하여 처리완료를 알려준다.


Event Loop는 요청 처리를 위하여 내부적으로 약간의 Thread와 프로세스를 사용한다.

이는 Non-blocking IO 또는 내부 처리를 위한 목적으로만 사용되며, 요청 처리 자체를 Thread로 하지는 않는다. 따라서 Node 서버는 Multi-Thread 방식의 서버에 비해 Thread 수와 오버헤드가 적다.


이벤트를 처리하는 Event Loop는 Single-Thread 로 이루어져 있다. 즉 하나의 Thread 안에서 요청이 처리된다. 그래서 이벤트 호출 측에는 비동기로 처리되지만, 처리작업 자체가 오래 걸리면 전체 서버 처리에 영향을 준다. 이는 Node.js의 치명적인 약점이다.



Node.js의 올바른 사용


Node.js는 Google Chrome V8 엔진 기반으로 동작하며, 내부의 Event Loop는 Single-Thread 기반에서 비동기 메시지를 처리한다. Event Loop는 고성능 병렬처리를 보장하도록 설계되어 있다. 따라서 이벤트에 의해 처리될 단위 작업이 짧은 시간 안에 처리된다면, Node.js의 고성능 장점을 극대화 할 수 있다.


처리 작업이 서버 CPU를 많이 소모한다거나 대용량 파일을 처리하는 작업이라면 Node.js는 올바른 선택이 아니다.

반대로 IO 작업이 적거나 단위 작업 소요시간이 짧은 어플리케이션의 경우 Node.js는 고성능을 보장한다.


Nods.js 개발자가 처리 로직을 동기방식으로 구성한다면, Node.js를 잘못 활용하는 것이다. 가능한 비동기 방식으로 처리하도록 프로그래밍 해야한다.




출처 : NEXTREE

Comments