Node.js 란?
JavaScript는 Browser에서 작동하는 JavaScript와 V8 JavaScript 엔진으로 빌드된 JavaScript 런타임 환경에서 돌아가는 JavaScript가 있다.
Node.js는 V8 JavaScript 엔진으로 빌드된 JavaScript 런타임 환경에서 돌아가는 JavaScript 이다.
런타임 환경에서 JavaScript로 서버를 구성할 수 있는 것일 뿐, Node.js 자체는 서버가 아니다.
node.js !== 서버
Browser에서 돌아가는 JavaScript와 런타임 환경에서 돌아가는 JavaScript는 차이가 있다.
한 가지의 차이를 예를 들면,
Browser에서 돌아가는 JavaScript에서 전역객체는 window 이지만,
런타임 환경에서 돌아가는 JavaScript에서 전역객체는 global 이다.
Node.js의 특징
Single Thread
Single Thread 기반의 non-blocking I/O(비동기 IO) 처리하는 특징을 가지고 있다.
하나의 쓰레드가 request를 받으면, 처리를 하고, File IO나 Network 처리 (데이타 베이스 접근)등이 있을 경우에는 IO 요청을 보내 놓고, 작업을 처리하다가, IO 요청이 끝나면 이벤트를 받아서 처리하는 이벤트 방식을 사용한다.
이로 인해서, CPU가 IO 응답을 기다리는 시간이 필요 없고, 대부분의 연산 작업에 사용되기 때문에 높은 효용성을 가질 수 있으며, 특히 하나의 Thread로 여러개의 요청을 처리하는 구조로 되어 있기 때문에, C10K 문제를 처리할 수 있는데 아주 최적화 되어 있다.C10K 문제 : 하나의 System에 얼마나 많은 Client가 붙을 수 있냐는 의문과 도전에서 제기되는 문제.
Non-Blocking I/O
I/O 작업은 유저레벨에서 직접 수행할 수 없다.
실제 I/O를 수행하는것은 커널레벨에서만 가능하다.
따라서 유저 프로세스(또는 쓰레드)는 커널에게 I/O를 요청해야한다.Blocking I/O :
I/O에서 블로킹 형태의 작업은 유저 프로세스가 커널에게 I/O를 요청하는 함수를 호출하고, 커널이 작업을 완료되면 함수가 작업 결과를 반환한다.
I/O 작업이 진행되는동안 유저 프로세스는 자신의 작업을 중단한채 대기해야한다.
I/O 작업이 CPU자원을 거의 쓰지 않기 때문에 이런 형태의 I/O는 리소스 낭비가 심하다.
I/O작업이 blocking 방식으로 구현되면 하나의 클라이언트가 I/O작업을 진행하면 해당 프로세스(또는 쓰레드)가 진행하는 작업을 중지하게 된다.
따라서 다른 클라이언트의 작업에 영향을 미치지 않게 하기 위해서 클라이언트 별로 별도의 쓰레드를 만들어 연결시켜주어야 할 것이다.Non-Blocking I/O :
I/O작업을 진행하는 동안 유저 프로세스의 작업을 중단시키지 않는다.
유저 프로세스가 커널에게 I/O를 요청하는 함수를 호출하면, 함수는 I/O를 요청한 다음 진행상황과 상관없이 바로 결과를 반환한다.
작업이 진행중일 때는 작업 진행중이란 의미를 반환한다.
이 결과를 받은 유저 프로세스는 다른 작업을 진행할 수 있다.
반환이 I/O의 진행시간과는 관계없이 빠르게 동작하기 때문에, 유저 프로세스는 자신의 작업을 오랜시간 중지하지 않고도 I/O 처리를 수행할 수 있다.
그러나 I/O 작업이 완료된 이후에 처리해야하는 후속 작업이 있다면, I/O 작업이 완료될 때까지 기다려야 한다.
따라서 이 후속 작업이 프로세스를 멈추지 않도록 만들기 위해, I/O 작업이 완료된 이후 후속 작업을 이어서 진행할 수 있도록 별도의 약속(Polling, Callback function 등)을 한다.
Event Driven
대부분의 웹서버는 사용자가 이벤트를 발생하기 까지 기다린다.
이벤트가 발생하기까지 자원(대기 시간 및 메모리)을 계속 소비하게 된다.
하지만 Event Driven는 비동기 방식으로 이벤트를 보내 놓고 사용자가 이벤트를 발생시켰을 때,
즉 입력장치로 데이터를 전송했을 때에만 웹서버가 연결해주는 방식이다.
그렇기 때문에 프로그램이 항상 이벤트를 기다리고 있지 않아도 되기 때문에 자원을 최소화 시킬수 있다.