이 글은 Understanding node.js 라는 글을 약간의 의역과 현재 시점(2014년 11월)에 맞도록 번역한 글입니다.
Node.js 는 일반적으로 두 가지의 반응을 이끌어낸다. "그래 이거야!" 라고 환호거나, 혹은 엄청 혼란스러워하면서 포기하는.
만약 지금까지 후자에 속해 있었다면, 노드에 대해 새롭게 설명해 보려고 한다.
- 노드는 커맨드라인 툴이다. 리눅스에는 tarball 형태로 다운받아서 소스를 컴파일해서 설치해야 한다.- 노드는 단순히 터미널 상에서 "node my_app.js" 라고 타이핑하는 것만으로 자바스크립트를 실행할 수 있다.- JS는 V8 이라는 자바스크립트 엔진으로 실행된다. (V8은 구글 크롬 내장 엔진이다)- 노드는 네트워크와 파일시스템에 접근할 수 있는 자바스크립트 API를 제공한다.
"하지만 난 이미 ruby, python, php, java에서 내가 필요한 모든 것을 할 수 있는데....!"
잘 알고 있다. 그리고 당신 말이 맞다. 노드는 미안하지만 당신의 일을 대신해주는 freaking unicorn 이 아니다. 단지 도구이며, 아마도 지금 당장은 당신의 주요 언어들을 완전히 대체하지도 못할 것이다.
"일단 핵심을 말해!"
맞다! 그러려고 했다! 노드는 기본적으로 동시에 몇 가지일을 처리해야할 필요가 있을때 매우 좋다.
혹시 한번이라도 코드를 작성한 뒤에 "이게 병렬로 돌아가면 얼마나 좋을까?" 라고 생각해 본 적이 있는가? 노드에서는 당신의 코드만 제외하고 모두 병렬로 돌아간다!
"응?"
맞다! 당신의 코드만 제외하고 모든 것이 병렬로 돌아간다! 이걸 이해하기 위해서는 먼저 코드는 왕이고 노드는 신하들의 군사라고 상상해야한다.
한 신하가 왕을 깨우고 무언가 필요한게 없는지 물으면서 하루가 시작된다.
왕은 해야할 일의 리스트를 그 신하에게 주고 다시 잠깐 눈을 붙인다. 신하는 이제 그 할일들을 그의 동료들과 함께 분류하고 일을 시작한다.
한 신하가 일을 마치면, 보고하기 위해 왕의 전 앞에 줄을 선다. 왕이 한 신하씩 불러들여 그가 한 일을 보고받는다.
왕은 때때로 더 많은 일을 그 때에 줄 수도 있다.
왕의 신하들은 각각 그들의 일을 병렬로 처리하고 있지만, 오직 한번에 한가지 결과를 보고하기 때문에 왕은 그것에 집중할 수 있다.
"그거 환상적인데? 근데 그런 비유말고 실제 코드로 말해줄수 없을까?"
물론이다! 간단한 노드 프로그램은 대략 아래와 같다:
var fs = require('fs') ,sys = require('sys'); fs.readFile('treasure-chamber-report.txt', function(report) { sys.puts("oh, look at all my money: "+report); }); fs.writeFile('letter-to-princess.txt', '...', function() { sys.puts("can't wait to hear back from her!"); });
당신의 코드는 노드에게 파일 읽기와 쓰기라는 두가지 일거리를 던지고, 그러고 난 다음엔 바로 잠들어버린다. 노드가 어떤 일을 끝마치고 나면 callback 이 실행된다.하지만 오직 한번에 한개의 콜백만 실행된다. 그 콜백의 수행이 종료되기 전까지 다른 콜백은 계속 그 라인에서 기다려야 한다. 게다가 어느 콜백이 먼저 실행될지는 보장할 수 없다.
"그래서 같은 데이터 스트럭쳐에 동시에 접근될 거에 대해서 내가 걱정할 필요가 없다는거야?"
그렇다! 그게 바로 JavaScript single-threaded / event loop design이다!
"엄청난데? 근데 내가 그걸 왜 써야하지?"
첫번째 이유는 효율때문이다. 웹 어플리케이션에서, 당신의 주요 응답 시간 비용은 대개 모든 데이터 쿼리 수행에 걸리는 시간의 합이다. 노드를 사용하게 되면, 당신의 모든 쿼리를 한꺼번에 실행할 수 있기 때문에 가장 느린 쿼리를 실행하느라 소모되는 응답시간을 감소시킬 수 있다.
다른 이유는 바로 자바스크립트이기 때문이다. 당신은 노드를 사용함으로 인해 브라우저와 백엔드 양쪽에서 코드를 공유할 수 있다. 자바스크립트는 또한 그 자체로도 이미 범용언어이기도 하다. 과거에 파이썬, 루비, 자바, PHP.....등 어떤 언어를 해왔건 간에, 아마도 당신은 JavaScript 언저리에는 계속 있어왔을 것이다.
그리고 마지막 이유는 속도다. V8은 지구상에서 가장 빠른 동적 인터프리터 언어가 되어가고 있다. 난 다른 어떤 언어도 자바스크립트가 지금 하고 있는 것만큼 거칠게 속도를 높여가고 있는걸 상상할 수 없다. 게다가, 노드의 I/O 는 정말 가벼워서 시스템의 가능한 최대의 I/O 성능을 끄집어내 줄 것이다.
"그래서 그럼 지금부터 모든 걸 노드로 만들어야 한다는거야?"
맞을 수도 있고 아닐수도 있다. 적어도 한번은 노드라는 망치를 한번 휘둘러 보면, 손바닥을 보는 것처럼 어떤것부터 시작해야 하는지 명확해 질 것이다. 하지만 당신이 지금 하고 있는 어떤 일이 거의 막바지에 이르렀다면, 당신은 아래와 같은 어떤 기준을 바탕으로 결단으로 내리고 싶을지도 모른다.
낮은 응답시간과 높은 동시성이 중요한가? 그렇다면 노드가 적합할 수 있다.
프로젝트의 규모는 어떠한가? 작은 프로젝트라면 괜찮을 것이다. 큰 프로젝트라면 반드시 주의깊게 계산해야 할 것이다. ( 사용 가능한 라이브러리와 자원들..)
"노드를 윈도우에서 돌릴 수 있기는 한거야?"
그렇다. 마이크로소프트의 적극적인 지원이 있은 후 윈도우용 노드도 나와 있으며, 심지어 Visual Studio에서 노드 관련 개발도 가능하다.
"노드를 사용해서 DOM에 접근 가능한건가?"
매우 좋은 질문이다! 답은 접근할 수 없다! DOM은 브라우저의 것이고, 노드의 자바스크립트 엔진(V8)은 감사하게도 완전히 DOM과 분리되어 있다. 하지만 DOM을 노드의 모듈로서 다루고 싶어하는 사람들이 있다. 이를 통해서 클라이언트쪽의 코드에 대한 단위테스트와 같은 매우 흥미로운 가능성이 열리게 된다. (역자주 : 현재는 PhantomJS 등이 존재하고 PhantomJS를 노드와 연결해주는 노드 모듈도 존재한다.)
"이벤트 주도 프로그래밍이 정말 어려운건가?"
그건 당신에게 달려있다. 만약 당신이 이미 AJAX 호출이나 브라우저 상의 사용자 이벤트 등을 학습했다면, 노드를 익히는건 그렇게 어려운 문제는 아니다.
좀 다른 얘기지만, 테스트 주도 개발은 정말 유지 보수 가능한 디자인을 마련하는 데 도움이 될 수 있다.