요 몇주간, node.js에 대해서 공부를 해오고 있습니다. 그간 공부해온 내용과, 기존에 node.js를 사용하셨던 분들과의 토론을 기반으로 node.js에 대한 장단점을 간략하게 정리합니다.
Node.JS에 대해서.
Node.js는 구글의 크롬 V8 자바스크립트 엔진을 기반으로 한, 고성능 네트워크 서버이다.
Single Thread 기반의 Event Loop를 기반으로 하고 있으며, File, Network 등에 대해서 비동기 IO 처리를 하는 서버 미들웨어이다.
근래에 들어서 다시금 node.js 가 많은 주목을 받고 있는데, Paypal이나 Groupon과 같은 굴지의 서비스 기업들이 내부 서버 플랫폼을node.js로 전환하는 것이 계기가 되고 있다.
Node.js의 장점
Node.js는 일반적으로 성능이 매우 빠른 고성능 서버로 알려져 있다. 이 고성능은 자바스크립트등에서 오는 것이 아니라, node.js의 기본적인 구조인 Single Thread기반의 비동기 IO 처리에서 온다. 하나의 쓰레드가 request를 받으면, 처리를 하고, File IO나 Network 처리 (데이타 베이스 접근)등이 있을 경우에는 IO 요청을 보내 놓고, 작업을 처리하다가, IO 요청이 끝나면 이벤트를 받아서 처리하는 이벤트 방식을 사용한다. 이로 인해서, CPU가 IO 응답을 기다리는 시간이 필요 없고, 대부분의 연산 작업에 사용되기 때문에 높은 효용성을 가질 수 있으며, 특히 하나의 Thread로 여러개의 요청을 처리하는 구조로 되어 있기 때문에, C10K 문제를 처리할 수 있는데 아주 최적화 되어 있다.
사실 node.js 자체의 구조로만 본다면 자바 보다 성능이 빠르다고 이야기할 수 없다. 이는 어디까지나 시나리오에 따라서이다. 상대적으로CPU Intensive한 작업이 없고, 많은 Connection을 동시에 처리해야 하는 시나리오 대해서는 아무래도 node.js의 성능이 압도적으로 높다.
아래의 그림을 보면 (참고: http://bcho.tistory.com/865)
데이타베이스 트랜젝션이 많은 애플리케이션의 경우 WAS(resin)+MySQL 구조가 nodejs + MySQL 구조보다 많이 빠름을 볼 수 있다.
그럼에도 불구하고 node.js가 인기가 있는 비결은 무엇일까? 이유는 javascript 에서 오는 생산성의 향상이라고 본다. HTML5 등으로 인해서 웹 개발에서 자바스크립트의 비중이 높아지게 되었고, 단순한 UI 수준만 필요하던 프론트앤드 개발자들에게도 수준 높은 개발 능력이 요구 되면서, 자바스크립트 기반의 프로그래밍 능력이 많이 향상되어 있던 차에, 백엔드에 대한 성역(?)에 대한 높은 접근 장벽이 있는 상태에서 node.js의 등장은 이러한 백엔드에 대한 진입 장벽을 깨버린 계기가 되었다. 자바스크립트 기술을 가지고 서버 백엔드를 개발할 수 있게 되었으며, 기존의 자바 프로그래밍등과 같은 서버 개발 언어보다 훨씬 높은 생산성을 보여준다 실제로 REST+DB API를 자바로 개발하였을 경우, 본인의 경우 이부분에 대해서 숙련이 되어 있음에도 불구하고, 30분~1시간정도가 소요되는 반면에, node.js를 공부해 가는 과정임에도 불구하고, 간단한 REST API의 경우 개발에 10분정도면 개발할 수 가 있었다.
Paypal도 node.js로 전환한 이유에 대해서 살펴보면, 프론트엔드와 백엔드 기술을 통합하여 생산성을 높이기 위함이라고 이야기 하고 있다.
본인이 생각하는 대단한 장점중의 하나는 node.js의 모듈중의 하나인 socket.io이다. 웹 개발이 점점 양방향이 되어가면서, 클라이언트와 connection을 맺고, 여기에 push를 보낼 수 있는 기술이 필요하다. HTML 5의 웹소켓이 좋은 기술이기는 하지만, 브라우져 호환성의 문제가 있는데 반해서, socket.io는 웹소켓을 포함한, AJAX 롤폴링등 여러개의 웹푸쉬를 abstraction하여, 브라우져에 상관 없이 개발자가 쉽게 socket.io API만 이용하면, 푸쉬를 구현할 수 있게 해주며, 싱글 쓰레드 기반의 멀티 플랙싱을 기반으로, 대용량 사용자에 대한 푸쉬 처리를 가능하게 해준다. (WAS는 Thread 수만큼 밖에 동시 connection 처리를 할 수 없기 때문에, node.js의 이 구조가 이런 대량 동시 Connection 처리에는 유리하다.)
또 하나의 장점을 들자면, 자바스크립트의 경우에는 멀티 쓰레드의 개념이 없다. 서버 프로그램에서 쓰레드간의 동기화 처리등이 중요하고 또한 복잡한점 중의 하나인데, 이러한 문제 자체를 제거 함으로써 서버 프로그래밍 자체를 매우 단순하게 만들어 버린 것이다.
운영 관점에서도 node.js의 restart 시간이 1sec 미만이기 때문에, 빠른 배포나 업그레이드 작업이 가능하다.
Node.js를 사용할 때 주의할점
Node.js는 자바스크립트와 Single Thread 모델에서 오는 장점이 있는 반면 여기서 오는 단점 역시 만만하지 않다. 기본적으로 Single thread 모델이기 때문에, 하나의 작업 자체가 시간이 많이 걸리면, 전체 시스템의 성능이 아주 급격하게 떨어진다. 그래서, 가벼운 (CPU를 많이 사용하지 않는) 작업 위주로 개발이 되어야 하고, 자바스크립트에서 오는 문제점은 자바나 다른 언어에 비해서 명시성이 떨어지기 때문에, 코드의 가독성이 자바언어에 비해서 상대적으로 낮기 때문에 유지 보수가 어려워질 수 있으며, 이벤트 Call back 을 형태를 기준으로 하기 때문에, 이러한 call back이 중첩될 경우 (이를 callback hell이라고 한다.) 코드의 가독성이 급격하게 떨어진다. (이를 해결하기 위한 프레임웍들이 있다.)
또한 자바스크립트와 같은 스크립트 언어의 특성상 해당 코드가 수행이 되어야 코드에서 에러가 나는지를 확인할 수 있고, 에러가 날 경우 프로세스 자체가 내려가기 때문에, node.js 를 사용하는 사람들에게 가장 많이 들려오는 단점이 “잘 죽어요.”이다.
물론 이부분은 watch dog이나 domain API 를 이용하면, 상당 부분 해결이 가능하지만, 이를 충분히 인지하고 설계에 사전 반영을 해야 하며, 발생가능한 에러를 잡아내기 위해서 개발 기간중에 테스트에 많은 집중을 해야한다.
다른 문제점으로는 single thread 모델이기 때문에, 멀티 코어 머신에서 CPU 사용을 최적화할 수 없다는 문제가 있다. 하나의 쓰레드는 하나의 물리적 코어밖에 사용하지 못하기 때문제 코어가 많은 시스템이라도 성능이 올라가지 않는다 그래서 설계시, Cluster 모듈등을 이용하여, 하나의 서버에서 여러개의 노드 프로세스를 사용하는 모델을 가지고 가야 하며, 또한, 세션등을 공유할 경우, 세션 공유용 redis와 같은 부가적인 인프라가 필요하다.
또한 V8 엔진을 기반으로 하는데, 이 V8 엔진은 Garbage collection 기반의 메모리 관리를 하기 때문에, GC시 CPU 사용률이 Spike를 치면서 순간적으로 서버를 멈추게할 수 있다는 문제점을 가지고 있다.
확장 모듈 관점에서도, Single Thread기반의 비동기 IO를 지원해야 하기 때문에, 노드 전용 모듈을 사용해야 하는데, 예를 들어 MySQL Connection Pool과 같은 경우에도 기존의 자바 기반의 dbcp와 같은 connection pool에 비해서 고급 기능이 적기 때문에 세밀한 High availability 구현등에는 한계를 가지고 있다.
그리고, node.js를 사용한 사람들에게서 들려오는 가장 많은 경험담은 자바스크립트 자체를 배우는 것보다는 프로그래밍 컨셉을 기존의 컨셉에서 Event 기반의 프로그래밍 컨셉으로 전환하는데 많은 시간이 걸렸다고 한다. 코드를 순차적으로 실행하는 것이 아니라, 비동기 방식으로 이벤트를 보내놓고, 그 응답에 대한 이벤트가 오면 핸들러를 통해서 처리 하는 형식이기 때문에, 기존 서버 프로그래밍 모델과는 많은 차이를 보인다.
[3/10 추가 내용] node.js의 async io 구현 부분은 os의 multiplexing library를 사용한다. 윈도우즈의 경우 iocp를, Unix 계열의 경우에는 select, epoll,kqueue등을 사용하는데, 각각의 장단점과 성능적인 차이를 가지고 있다. 그래서, 운영하고자 하는 OS에 따라서 OS 설정이 다리고, 또한 multiplexing 라이브러리에 따라서 성능이 차이가 나기 때문에, node.js 운영전에, 운영할 OS에서 테스트 및 튜닝을 해보기를 권장한다.
개발 관점에서는 빠르고 쉬운 장점이 있지만, 반대로 운영 관점에서는 테스트, 장애 대응, 디버깅등에 대해서는 신경써야 할 부분이 훨씬 더 많다.
이런 단점에도 불구하고 탁월한 생산성과 이미 상당히 커진 커뮤니티와 에코 시스템에서 오는 장점 때문에, 널리 사용되고 있고 앞으로도 널리 사용될 것으로 보인다.
기존의 자바, 스프링,WAS와 같은 생태계가 node.js 기반으로 자바스크립트쪽에서 새롭게 생성되고 있는 느낌이라고나 할까?
지금 아직도 node.js를 공부중에 있습니다. 나중에 끝나면 전체적으로 한번 정리해서 튜토리얼을 올리도록 하겠습니다.
#1 – node.js의 소개와 내부 구조 http://bcho.tistory.com/881
#2 - 설치와 개발환경 구축 http://bcho.tistory.com/884
#3 - Event,Module,NPM http://bcho.tistory.com/885
#4 - 웹 개발 프레임웍 Express 1/2 - http://bcho.tistory.com/887